SuperSocket在.Net5中使用——Command篇

背景:Command命令单拿出来学习,其实是因为纯看你的使用习惯,你如果不想用内置的这种电文匹配业务处理的逻辑,完全可以自己在UsePackageHandler方法中进行相应的业务处理;或者你的TReceivePackage包类型没有继承IKeyedPackageInfo<T>,这个时候也不用内置Command处理逻辑了。

当然,Command和过滤器的使用还是有很多优点,使你的业务处理代码更加简洁清晰,让你的代码结构更加清晰,可以利用过滤器监听业务处理以及添加一些隔离于业务处理代码的处理;接下来就一起学习一下Command怎么用

现在就以启动篇中定义的场景,现在要创建一个Command来处理接受添加(Add)用户命令的业务操作;数据结构和过滤器和上文“启动篇”中一样,但要注意的是数据结构类要继承IKeyedPackageInfo<T>

接受到的电文长这样:

1.新建名称为Add的Command

    [Command(Key = "add")]
    public class Add : IAsyncCommand<MyPackage>
    {
        public async ValueTask ExecuteAsync(IAppSession session, MyPackage package)
        {
            //TODO 你的业务
            string sql = $" insert into Users(UserName) values ('{package.UserName}')";
            Thread.Sleep(1000);
            await session.SendAsync(Encoding.UTF8.GetBytes(package.UserName));
        }
    }

这里注意的是:

(1).特性Key可以没有,没有情况下Command的路由就是按照key和Command名称去匹配

(2).指定Comand的key的时候,只能按key,不能按Command名称去匹配了

2.注册Command

这里要注意的是,使用Command去处理业务的话,就不能再使用UsePackageHandler方法了,因为使用UsePackageHandler会覆盖掉Command的相关方法

            var host = SuperSocketHostBuilder.Create<MyPackage, MyFilter>()
    //.UsePackageHandler(async (s, p) =>
    //{
    //    // handle your package over here
    //    await s.SendAsync(Encoding.UTF8.GetBytes(p.Key + "\r\n"));
    //})
      .UseCommand((commandOptions) =>
      {
          //注册添加用户命令
          commandOptions.AddCommand<Add>();
          //...add else command
      })
    .Build();
            await host.RunAsync();

现在就可以测试一下了:

发现key是“add”时,会执行Add(创建的Command)里边的异步方法ExecuteAsync

3.接下来加上Command Filter,Command Filter就相当于ASP.MVC中的AOP的动作过滤器,会在命令执行之前或之后被调用。

新建继承AsyncCommandFilterAttribute或者CommandFilterAttribute的CommandFilter

    /// <summary>
    /// Command过滤器
    /// </summary>
    public class AddCommandFilterAttribute : CommandFilterAttribute
    {
        public override void OnCommandExecuted(CommandExecutingContext commandContext)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"添加用户之后");
        }

        public override bool OnCommandExecuting(CommandExecutingContext commandContext)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "添加用户之前");
            return true;
        }
    }

    /// <summary>
    /// 异步Command过滤器
    /// </summary>
    public class AsyncAddCommandFilterAttribute : AsyncCommandFilterAttribute
    {
        public override async ValueTask OnCommandExecutedAsync(CommandExecutingContext commandContext)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "添加用户之后 Async");
            await Task.Delay(0);
        }

        public override async ValueTask<bool> OnCommandExecutingAsync(CommandExecutingContext commandContext)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "添加用户之前 Async");
            await Task.Delay(0);
            return true;
        }
    }

将特性添加到相应Command上:

测试效果:

另外还有全局过滤器,就是在定义的所有Command的执行之前和之后需要做什么操作,执行顺序在其他指定Filter之前

        public class AsyncMyGlobalFiterAttribute : AsyncCommandFilterAttribute
        {
            public override async ValueTask OnCommandExecutedAsync(CommandExecutingContext commandContext)
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "处理电文之后 Async");
                await Task.Delay(0);
            }

            public override async ValueTask<bool> OnCommandExecutingAsync(CommandExecutingContext commandContext)
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "处理电文之前 Async");
                await Task.Delay(0);
                string commandName = commandContext.CurrentCommand.ToString();
                MyPackage myPackage = (MyPackage)commandContext.Package;
                if (myPackage.UserName == "Admin")
                {
                    //举例用户名为Admin时不做Command处理
                    return false;
                }
                return true;
            }
        }

 注册全局过滤器

      .UseCommand((commandOptions) =>
      {
          //注册添加用户命令
          commandOptions.AddCommand<Add>();
          //...add else command

          //注册全局过滤器
          commandOptions.AddGlobalCommandFilter<AsyncMyGlobalFiterAttribute>();
      })

测试

SuperSocket.Core中的Command就学习到这

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,但是你却可以使用 SuperSocket 很容易的开发出一款 Socket 服务器端软件,例如游戏服务器,GPS 服务器, 工业控制服务和数据采集服务器等等。 SuperSocket具有如下特点: 高性能的事件驱动通信; 非常简单易用; 你只需要通过创建几个类就能获得一个健壮的 Socket 服务器; 内置的命令行协议让你能够迅速创建一个网络命令行接口服务器; 强大且高性能的协议解析实现工具帮你简化了网络数据的分析工作; 灵活的配置功能和友好的配置 API; 多监听器支持; 让你在一个服务器实例内监听多个端口; 多服务器实例托管的支持让你从容面对复杂的部署需求; 应用程序域和进程级别的隔离能够满足你大部分的宿主场景; 内置的 SSL/TLS 加密支持; 会话级别的发送队列能够让你通过会话并发的发送数据,并保持高性能和可控性; SuperSocket 的命令处理模式让你的业务逻辑更清晰,更有条理; 优良的可扩展 API 支持: Command Filter, Connection Filter, Command Loader; 可替换的日志架构允许你使用你喜欢的日志组件; 动态语言的支持; 允许你用 Python 之类的脚本语言来实现命令; 与 Mono/Linux 保持二进制级别的兼容; Windows Azure 的支持; 内置你可以直接用于 Flash 或 Silverlight 客户端的 Socket 策略服务器;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值