背景:上文介绍了基本概念,相比于官网来说不全,但也是基本能用到的概念了。本文继续将从启动SuperSocket的角度,继续介绍使用SuperSocket
1.两种启动方式
(1)通用启动方式,在任何.net5程序中都可以使用
public static async Task Main(string[] args)
{
var host = SuperSocketHostBuilder.Create()
.UsePackageHandler(async (s, p) => {
//对接收到的数据进行业务处理,并可以选择是否反馈给客户端数据
await s.SendAsync(Encoding.UTF8.GetBytes(p + "rn"));
})
.Build();
//启动SuperSocketHostBuilder
await host.RunAsync();
}
上述几行代码就可以启动一个简单的Server:
(2)在.Net Core Web中启动,这样就可以在一个Web网站或者WebApi中同时启动一个Socket Server
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
})
.AsSuperSocketHostBuilder()
.UsePackageHandler(async (s, p) =>
{
//对接收到的数据进行业务处理,并可以选择是否反馈给客户端数据
await s.SendAsync(Encoding.UTF8.GetBytes(p + "rn"));
});
2.两种配置方式
在SuperSocket中,你可以很好的针对Server进行设置属性,并轻松的开启多个Server
(1)“概念篇”中已经介绍了SuperSocket的配置文件,通过在appsettings.json中添加serverOptions节点来配置Server选项,以及开启监听多个Server
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"serverOptions": {
"name": "TestServer",
"listeners": [
{
"ip": "127.0.0.1",
"port": 4040,
"sendTimeout": 20000,
"maxPackageLength": 2048
},
{
"ip": "Any",
"port": 4041
}
]
},
"AllowedHosts": "*"
}
上述配置项就同时监听了本机的4040和4041端口
(2)通过ConfigureSuperSocket方法配置需要
var host = SuperSocketHostBuilder.Create() .ConfigureSuperSocket(options => { //配置SuperSocket选项 options.Name = "TestServer"; options.ReceiveBufferSize = 2048; options.SendTimeout = 20000; options.Listeners = new List (){ new ListenOptions{ Ip="Any", Port = 4042 } }; }) .UsePackageHandler(async (s, p) => { //对接收到的数据进行业务处理,并可以选择是否反馈给客户端数据 await s.SendAsync(Encoding.UTF8.GetBytes(p + "rn")); }) .Build();
需要注意的是,这样会覆盖配置文件中关于SuperSocket的配置选项 。
3.使用过滤器
通过使用内置过滤器和自定义过滤器和进一步介绍SuperSocket中Filter的使用
(1)使用内置过滤器FixedSizePipelineFilter
public class MyFixedSizePipelineFilter : FixedSizePipelineFilter{ //规定一个长度为15有效数据的过滤器 public MyFixedSizePipelineFilter() : base(15) { } }
过滤器绑定SuperSocket
var host = SuperSocketHostBuilder.Create() .ConfigureSuperSocket(options => { //配置SuperSocket选项 options.Name = "TestServer"; options.ReceiveBufferSize = 2048; options.SendTimeout = 20000; options.Listeners = new List (){ new ListenOptions{ Ip="Any", Port = 4042 } }; }) .UsePackageHandler(async (s, p) => { //对接收到的数据进行业务处理,并可以选择是否反馈给客户端数据 await s.SendAsync(Encoding.UTF8.GetBytes(p + "rn")); }) .Build();
启动发现,过滤器这边每次会截取过滤出长度为15的数据包,并解析成StringPackageInfo;数据长度不够时会放置到缓冲区等待拼接下次的数据包
(2)自定义过滤器
官网上说内置过滤器能满足90%的场景,但是我觉得很多类型电文不会完全符合,这样可以在借鉴官网过滤数据的逻辑,自定义重写自己的数据过滤器,最主要的自己写的过滤器可以不必是命令行协议,即结束符不用必须得带rn
举例,现在有一个电文规定结束符是0x0A,数据包总长度为17,数据结构为:
想必这样的电文结构大家平时接触很多,那现在就开始自己写过滤器了:
////// 自定义数据过滤器 /// public class MyFilter : IPipelineFilter{ private int _size = 17; private readonly byte[] _terminator= new byte[] { 0x0A}; public IPackageDecoder Decoder { get; set; } public object Context { get; set; } public IPipelineFilter NextFilter => null; public MyPackage Filter(ref SequenceReader reader) { if (reader.Length < _size) { //如果长度小于规定协议数据包长度,不予解析 return null; } if (!reader.TryReadTo(out ReadOnlySequence sequence, _terminator, advancePastDelimiter: false)) { //如果结束符不是指定结束符,不予解析 return null; } ReadOnlySequence buffer = reader.Sequence.Slice(0, 6);//type string type = EncodingExtensions.GetString(Encoding.UTF8, buffer).Trim(); ReadOnlySequence buffer1 = reader.Sequence.Slice(5, 10); string userName= EncodingExtensions.GetString(Encoding.UTF8, buffer1).Trim(); MyPackage myPackage = new MyPackage { Type=type,UserName=userName }; while (reader.TryRead(out _)) ; return myPackage; } public void Reset() { } }
这个自定义过滤器中,继承IPipelineFilter接口,实现Filter方法来实现对数据包长度,结束符的检验,以及解析为数据结构。
执行结果,正常过滤解析后返回原数据:
接收数据不规范时:
可以看到,接收数据不规范时,会过滤掉不处理,更不会进行后续的业务操作。
以上就是SuperSocket的简单和基本使用方法,接下来一篇介绍Command的使用方法



