命令过滤器

关键字: 命令过滤器, 命令, 过滤器, OnCommandExecuting, OnCommandExecuted

SuperSocket 中的命令过滤器看起来有些像 ASP.NET MVC 中的 Action Filter,你可以用它来做命令执行的拦截,命令过滤器会在命令执行前和执行后被调用。

命令过滤器必须继承于 Attribute 类 CommandFilterAttribute:

  1. /// <summary>
  2. /// Command filter attribute
  3. /// </summary>
  4. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  5. public abstract class CommandFilterAttribute : Attribute
  6. {
  7. /// <summary>
  8. /// Gets or sets the execution order.
  9. /// </summary>
  10. /// <value>
  11. /// The order.
  12. /// </value>
  13. public int Order { get; set; }
  14. /// <summary>
  15. /// Called when [command executing].
  16. /// </summary>
  17. /// <param name="commandContext">The command context.</param>
  18. public abstract void OnCommandExecuting(CommandExecutingContext commandContext);
  19. /// <summary>
  20. /// Called when [command executed].
  21. /// </summary>
  22. /// <param name="commandContext">The command context.</param>
  23. public abstract void OnCommandExecuted(CommandExecutingContext commandContext);
  24. }

你需要为你的命令过滤器实现下面两个方法:

OnCommandExecuting: 此方法将在命令执行前被调用;

OnCommandExecuted: 此方法将在命令执行后被调用;

Order: 此属性用于设置多个命令过滤器的执行顺序;

下面的代码定义了一个命令过滤器 LogTimeCommandFilterAttribute 用于记录执行时间超过5秒钟的命令:

  1. public class LogTimeCommandFilter : CommandFilterAttribute
  2. {
  3. public override void OnCommandExecuting(CommandExecutingContext commandContext)
  4. {
  5. commandContext.Session.Items["StartTime"] = DateTime.Now;
  6. }
  7. public override void OnCommandExecuted(CommandExecutingContext commandContext)
  8. {
  9. var session = commandContext.Session;
  10. var startTime = session.Items.GetValue<DateTime>("StartTime");
  11. var ts = DateTime.Now.Subtract(startTime);
  12. if (ts.TotalSeconds > 5 && session.Logger.IsInfoEnabled)
  13. {
  14. session.Logger.InfoFormat("A command '{0}' took {1} seconds!", commandContext.CurrentCommand.Name, ts.ToString());
  15. }
  16. }
  17. }

然后通过增加属性的方法给命令 "QUERY" 应用此过滤器:

  1. [LogTimeCommandFilter]
  2. public class QUERY : StringCommandBase<TestSession>
  3. {
  4. public override void ExecuteCommand(TestSession session, StringCommandInfo commandData)
  5. {
  6. //Your code
  7. }
  8. }

如果你想应用次过滤器给所有的命令, 你可以向下面的代码这样将此命令过滤器的属性加到你的 AppServer 类上面去:

  1. [LogTimeCommandFilter]
  2. public class TestServer : AppServer<TestSession>
  3. {
  4. }

你可以通过将 commandContext's 的 Cancel 属性设为 True 来取消当前命令的执行:

  1. public class LoggedInValidationFilter : CommandFilterAttribute
  2. {
  3. public override void OnCommandExecuting(CommandExecutingContext commandContext)
  4. {
  5. var session = commandContext.Session as MyAppSession;
  6. //If the session is not logged in, cancel the executing of the command
  7. if (!session.IsLoggedIn)
  8. commandContext.Cancel = true;
  9. }
  10. public override void OnCommandExecuted(CommandExecutingContext commandContext)
  11. {
  12. }
  13. }