十年河東,十年河西,莫欺少年窮
學無止境,精益求精
1、新建控制檯程序並引入包
dotnet add package SuperSocket.Server
2、書寫代碼
using System; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using SuperSocket; using SuperSocket.ProtoBase; namespace MySupersocket // Note: actual namespace depends on the project name. { internal class Program { static async Task Main(string[] args) { var Listeners = new List<ListenOptions>() { new ListenOptions { Ip = "Any", Port = 4040 }, new ListenOptions { Ip = "Any", Port = 8040 }}; var host = SuperSocketHostBuilder .Create<StringPackageInfo, CommandLinePipelineFilter>().UsePackageHandler(async (session, package) => { var result = 0; //接收的包 類型爲StringPackageInfo 也就是字符串 Console.WriteLine($"package如下:"); Console.WriteLine(JsonConvert.SerializeObject(package)); //session 可以理解爲客戶端的某個連接 Console.WriteLine($"session如下:"); //客戶端關閉連接原因 Console.WriteLine("ChannelCloseReason:" + session.Channel.CloseReason); //客戶端最後活躍時間 Console.WriteLine("LastActiveTime:" + session.LastActiveTime); //服務器偵聽的IP+端口,也就是偵聽地址 Console.WriteLine("LocalEndPoint:" + session.LocalEndPoint); //客戶端IP+端口,也就是客戶端地址 Console.WriteLine("RemoteEndPoint:" + session.RemoteEndPoint); //當前客戶端連接數量 Console.WriteLine("SessionCount:" + session.Server.SessionCount); //當前服務器偵聽的狀態 Console.WriteLine("ServerState:" + session.Server.State); //當前鏈接的唯一標識 Console.WriteLine("SessionID:" + session.SessionID); //當前鏈接的開始時間 Console.WriteLine("StartTime:" + session.StartTime); //當前鏈接的狀態 Console.WriteLine("State:" + session.State); switch (package.Key.ToUpper()) { case ("ADD"): result = package.Parameters .Select(p => int.Parse(p)) .Sum(); break; case ("SUB"): result = package.Parameters .Select(p => int.Parse(p)) .Aggregate((x, y) => x - y); break; case ("MULT"): result = package.Parameters .Select(p => int.Parse(p)) .Aggregate((x, y) => x * y); break; } // \r\n 爲鍵盤迴車換行 await session.SendAsync(Encoding.UTF8.GetBytes(result.ToString() + "\r\n")); }).ConfigureSuperSocket(options => { options.Name = "Echo Server"; options.Listeners = Listeners; }).ConfigureLogging((hostCtx, loggingBuilder) => { loggingBuilder.AddConsole(); }).Build(); await host.RunAsync(); Console.Read(); } } }
3、使用telnet測試
telnet 127.0.0.1 8040
NetCore輸出
4、概念解讀
4.1、Package Type(包類型/內置行協議)
TextPackageInfo
包類型 TextPackageInfo(SuperSocket.ProtoBase.TextPackageInfo,SuperSocket.ProtoBase) 是在 SuperSocket 中定義的最簡單的數據包。它代表這類型的包僅包含一個字符串。
namespace SuperSocket.ProtoBase { public class TextPackageInfo { public string Text { get; set; } public override string ToString() { return Text; } } }
StringPackageInfo
StringPackageInfo是簡單的包括鍵值和body的數據結構,一些內置Filter默認將過濾好的數據解析爲StringPackageInfo類。StringPackageInfo類使用了一個空格來分割請求key和參數
namespace SuperSocket.ProtoBase { public class StringPackageInfo : IKeyedPackageInfo<string>, IStringPackage { public string Key { get; set; } public string Body { get; set; } public string[] Parameters { get; set; } } }
4.2、AppSession
AppSession
根據官方描述,AppSession代表一個和客戶端的邏輯連接,基於連接的操作應該定於在該類之中。你可以用該類的實例發送數據到客戶端,接收客戶端發送的數據或者關閉連接。
對於實現固定頭協議來說,AppSession不是必須的,但是站在應用服務器的角度來說,一個AppSession對象就是一個客戶端連接,該客戶端起碼會含有標識自己的信息,這是應用服務器所需要的。
4.3、PipelineFilter 行協議過濾器
SuperSocket 提供了這些 PipelineFilter 模版:
TerminatorPipelineFilter (SuperSocket.ProtoBase.TerminatorPipelineFilter, SuperSocket.ProtoBase)
TerminatorTextPipelineFilter(SuperSocket.ProtoBase.TerminatorTextPipelineFilter, SuperSocket.ProtoBase)
LinePipelineFilter (SuperSocket.ProtoBase.LinePipelineFilter, SuperSocket.ProtoBase)
CommandLinePipelineFilter (SuperSocket.ProtoBase.CommandLinePipelineFilter, SuperSocket.ProtoBase)
BeginEndMarkPipelineFilter (SuperSocket.ProtoBase.BeginEndMarkPipelineFilter, SuperSocket.ProtoBase)
FixedSizePipelineFilter (SuperSocket.ProtoBase.FixedSizePipelineFilter, SuperSocket.ProtoBase)
FixedHeaderPipelineFilter (SuperSocket.ProtoBase.FixedHeaderPipelineFilter, SuperSocket.ProtoBase)
1、TerminatorPipelineFilter 終止符過濾器(過濾解析指定終止符之前的數據,默認解析成StringPackageInfo類)
2、TerminatorTextPipelineFilter 終止符文本管道過濾器(過濾解析指定終止符之前的數據,默認解析成TextPackageInfo類)
3、LinePipelineFilter 管路過濾器(最普通的過濾器,除了命令行限制,其他無限制,默認解析成TextPackageInfo類)
4、CommandLinePipelineFilter 命令行管道過濾器(最普通的過濾器,除了命令行限制,其他無限制,默認解析成StringPackageInfo類)
5、BeginEndMarkPipelineFilter 有固定開始結束標記管道過濾器(根據開始和結束符過濾有效數據,默認解析成StringPackageInfo類)
6、FixedSizePipelineFilter 固定長度過濾器(只解析指定長度的數據,當數據長度小於指定長度時,會報錯並斷開連接重連,默認解析成StringPackageInfo類)
7、FixedHeaderPipelineFilter 固定開頭(長度)管道過濾器(通過指定數據包開頭長度,重寫GetBodyLengthFromHeader方法,從開頭數據包中獲取有效數據包的長度,默認解析成StringPackageInfo類)
參考博客:https://blog.csdn.net/weixin_33277597/article/details/122051837