SuperSocket 2.0学习04:命令和命令过滤器

官方学习资料:命令和命令过滤器

本文开发环境:Win10 + VS2019 + .NetCore 3.1 + SuperSocket 2.0.0-beta.8。

Gitee:SuperSocketV2Sample

1、创建项目

使用VS2019创建.NET Core控制台程序,选择.Net Core 3.1,通过NuGet引入SuperSocket(2.0.0-beta.8)。

2、添加配置文件

在项目根目录添加appsettings.json配置文件,并设置其文件属性为“如果较新则复制”。配置文件内容不再赘述。

3、命令和命令过滤器

命令相关类

using System.Text;
using System.Threading.Tasks;
using SuperSocket;
using SuperSocket.Command;
using SuperSocket.ProtoBase;

namespace SuperSocketV2Sample.Command.Commands
{
    public abstract class BaseCommand : IAsyncCommand<StringPackageInfo>
    {
        public async ValueTask ExecuteAsync(IAppSession session, StringPackageInfo package)
        {
            await Task.Delay(0);

            var result = GetResult(package);

            //发送消息给客户端
            await session.SendAsync(Encoding.UTF8.GetBytes(result + "\r\n"));
        }

        protected abstract string GetResult(StringPackageInfo package);
    }
}

using System;
using System.Linq;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Server;

namespace SuperSocketV2Sample.Command.Commands
{
    /// <summary>
    /// 加法命令
    /// </summary>
    [Command(Key = "ADD")]
    [AsyncKeyUpperCommandFilter]
    public class AddCommand : BaseCommand
    {
        protected override string GetResult(StringPackageInfo package)
        {
            string result;
            try
            {
                result = package.Parameters
                    // ReSharper disable once ConvertClosureToMethodGroup
                    .Select(t => int.Parse(t))
                    .Sum()
                    .ToString();
            }
            catch (Exception e)
            {
                result = e.Message;
            }

            return result;
        }
    }
}

using System;
using System.Linq;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Server;

namespace SuperSocketV2Sample.Command.Commands
{
    /// <summary>
    /// 减法命令
    /// </summary>
    [Command(Key = "SUB")]
    [AsyncKeyUpperCommandFilter]
    public class SubCommand : BaseCommand
    {
        protected override string GetResult(StringPackageInfo package)
        {
            string result;
            try
            {
                result = package.Parameters
                    // ReSharper disable once ConvertClosureToMethodGroup
                    .Select(t => int.Parse(t))
                    .Aggregate((x, y) => x - y)
                    .ToString();
            }
            catch (Exception e)
            {
                result = e.Message;
            }

            return result;
        }
    }
}

using System;
using System.Linq;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Server;

namespace SuperSocketV2Sample.Command.Commands
{
    /// <summary>
    /// 乘法命令
    /// </summary>
    [Command(Key = "MUL")]
    [AsyncKeyUpperCommandFilter]
    public class MulCommand : BaseCommand
    {
        protected override string GetResult(StringPackageInfo package)
        {
            string result;
            try
            {
                result = package.Parameters
                    // ReSharper disable once ConvertClosureToMethodGroup
                    .Select(t => int.Parse(t))
                    .Aggregate((x, y) => x * y)
                    .ToString();
            }
            catch (Exception e)
            {
                result = e.Message;
            }

            return result;
        }
    }
}

using System;
using System.Globalization;
using System.Linq;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Server;

namespace SuperSocketV2Sample.Command.Commands
{
    /// <summary>
    /// 除法命令
    /// </summary>
    [Command(Key = "DIV")]
    [AsyncKeyUpperCommandFilter]
    public class DivCommand : BaseCommand
    {
        protected override string GetResult(StringPackageInfo package)
        {
            string result;
            try
            {
                result = package.Parameters
                    // ReSharper disable once ConvertClosureToMethodGroup
                    .Select(t => float.Parse(t))
                    .Aggregate((x, y) => x * 1f / y)
                    .ToString(CultureInfo.InvariantCulture);
            }
            catch (Exception e)
            {
                result = e.Message;
            }

            return result;
        }
    }
}

using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Server;

namespace SuperSocketV2Sample.Command.Commands
{
    /// <summary>
    /// ECHO命令
    /// </summary>
    [Command(Key = "ECHO")]
    [AsyncKeyUpperCommandFilter]
    public class EchoCommand : BaseCommand
    {
        protected override string GetResult(StringPackageInfo package)
        {
            return package.Body;
        }
    }
}

命令过滤器

using System;
using SuperSocket.Command;
using System.Threading.Tasks;
using SuperSocket.ProtoBase;

namespace SuperSocketV2Sample.Command.Server
{
    public class AsyncKeyUpperCommandFilterAttribute : AsyncCommandFilterAttribute
    {
        public override async ValueTask<bool> OnCommandExecutingAsync(CommandExecutingContext commandContext)
        {
            if (commandContext.Package is StringPackageInfo package)
            {
                Console.WriteLine($"session ip: {commandContext.Session.RemoteEndPoint}, " +
                                  $" command: {package.Key}");
            }

            await Task.Delay(0);
            return true;
        }

        public override async ValueTask OnCommandExecutedAsync(CommandExecutingContext commandContext)
        {
            await Task.Delay(0);
        }
    }
}

4、测试代码 

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SuperSocket;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocketV2Sample.Command.Commands;

namespace SuperSocketV2Sample.Command
{
    class Program
    {
        static async Task Main()
        {
            //创建宿主:用Package的类型和PipelineFilter的类型创建SuperSocket宿主。
            var host = SuperSocketHostBuilder.Create<StringPackageInfo, CommandLinePipelineFilter>()
                //注册用于处理连接、关闭的Session处理器
                .UseSessionHandler(async (session) =>
                {
                    Console.WriteLine($"session connected: {session.RemoteEndPoint}");

                    //发送消息给客户端
                    var msg = $@"Welcome to TelnetServer: {session.RemoteEndPoint}";
                    await session.SendAsync(Encoding.UTF8.GetBytes(msg + "\r\n"));
                }, async (session, reason) =>
                {
                    await Task.Delay(0);
                    Console.WriteLine($"session {session.RemoteEndPoint} closed: {reason}");
                })
                .UseCommand((commandOptions) =>
                {
                    //注册命令
                    commandOptions.AddCommand<AddCommand>();
                    commandOptions.AddCommand<DivCommand>();
                    commandOptions.AddCommand<MulCommand>();
                    commandOptions.AddCommand<SubCommand>();
                    commandOptions.AddCommand<EchoCommand>();
                })
                //配置日志
                .ConfigureLogging((hostCtx, loggingBuilder) =>
                {
                    loggingBuilder.AddConsole();
                })
                .Build();
            await host.RunAsync();
        }
    }
}
posted @ 2021-04-03 23:32  xhubobo  阅读(1036)  评论(0编辑  收藏  举报