SuperSocket 是一個輕量級, 跨平臺並且可擴展的 .Net/Mono Socket 服務器程序框架。你無須瞭解如何使用 Socket, 如何維護 Socket 鏈接和 Socket 如何工做,可是你卻可使用 SuperSocket 很容易的開發出一款 Socket 服務器端軟件,例如遊戲服務器,GPS 服務器, 工業控制服務和數據採集服務器等等。windows
PS:上面這句話複製官網的,好了,總之告訴你們SuperSocket已經很強大、很穩定、方便。服務器
若是你沒有Socket基礎,首先要了解協議;本人兩年都在作智能穿戴,接觸大量硬件廠商,發現大部分是「帶起止符的協議」(BeginEndMarkReceiveFilter)或者「頭部格式固定而且包含內容長度的協議」(FixedHeaderReceiveFilter)網絡
我簡單介紹這兩種協議。session
代碼上我就二選一介紹FixedHeaderReceiveFilter吧app
首先新建項目,在Nuget管理器上搜索「SuperSocket」安裝「SuperSocket」和「SuperSocket.Engine」框架
接下來你須要實現socket
一、 IRequestInfo(請求信息,一次數據包)ide
public class MyRequestInfo : IRequestInfo { public MyRequestInfo(byte[] header, byte[] bodyBuffer) { Key = ((header[0] * 256) + header[1]).ToString(); Data = bodyBuffer; } /// <summary> /// 協議號對應自定義命令Name,會觸摸自定義命令 /// </summary> public string Key { get; set; } /// <summary> /// 正文字節碼 /// </summary> public byte[] Data { get; set; } /// <summary> /// 正文文本,大部分協議都不是這麼玩的 /// </summary> public string Body { get { return Encoding.UTF8.GetString(Data); } } }
二、 FixedHeaderReceiveFilter<IRequestInfo>(數據包的解析)性能
public class MyReceiveFilter : FixedHeaderReceiveFilter<MyRequestInfo> { /// +-------+---+-------------------------------+ /// |request| l | | /// | name | e | request body | /// | (2) | n | | /// | |(2)| | /// +-------+---+-------------------------------+ public MyReceiveFilter() : base(4) { } protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) { return (int)header[offset + 2] * 256 + (int)header[offset + 3]; } protected override MyRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length) { var body = bodyBuffer.Skip(offset).Take(length).ToArray(); return new MyRequestInfo(header.Array, body); } }
三、 AppSession<TAppSession, TRequestInfo>(Session會話,服務端管理客戶端的鏈接、信息)測試
public class MySession : AppSession<MySession, MyRequestInfo> { public MySession() { }protected override void OnSessionStarted() { } protected override void OnInit() { base.OnInit(); } protected override void HandleUnknownRequest(MyRequestInfo requestInfo) { } protected override void HandleException(Exception e) { } protected override void OnSessionClosed(CloseReason reason) { base.OnSessionClosed(reason); } }
四、 AppServer<TAppSession, TRequestInfo>(監聽服務)
public class MyServer : AppServer<MySession, MyRequestInfo> { /// <summary> /// 經過配置文件安裝服務從這裏啓動 /// </summary> public MyServer() : base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>()) { this.NewSessionConnected += MyServer_NewSessionConnected; this.SessionClosed += MyServer_SessionClosed; } /// <summary> /// winform啓動,不使用這裏的事件 /// </summary> public MyServer(SessionHandler<MySession> NewSessionConnected, SessionHandler<MySession, CloseReason> SessionClosed) : base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>()) { this.NewSessionConnected += NewSessionConnected; this.SessionClosed += SessionClosed; } protected override void OnStarted() { //啓動成功 LogHelper.WriteLog(string.Format("Socket啓動成功:{0}:{1}", this.Config.Ip, this.Config.Port)); } void MyServer_NewSessionConnected(MySession session) { //鏈接成功 } void MyServer_SessionClosed(MySession session, CloseReason value) { } }
好了,你能夠跑起來
var config = new SuperSocket.SocketBase.Config.ServerConfig() { Name = "SSServer", ServerTypeName = "SServer", ClearIdleSession= true, //60秒執行一次清理90秒沒數據傳送的鏈接 ClearIdleSessionInterval = 60, IdleSessionTimeOut = 90, MaxRequestLength = 2048, //最大包長度 Ip = "Any", Port = 18888, MaxConnectionNumber = 100000, }; app = new MyServer(app_NewSessionConnected, app_SessionClosed); LogHelper.SetOnLog(new LogHelper.LogEvent((m) => { txtAll.Text = string.Join(" ", m, "\r\n"); txtAll.Select(txtAll.TextLength, 0); txtAll.ScrollToCaret(); })); app.Setup(config); if (!app.Start()) { LogHelper.WriteLog(string.Format("Socket {0}:{1}啓動失敗,請檢查權限或端口是否被佔用!", config.Ip, config.Port)); }
有關性能,本人在本地(筆記本i5 4200H/12G)測試10萬鏈接同時在線,沒有問題;固然啦,跟業務有關,好比你要作的是IM羣聊,數據到服務端須要頻繁計算。
最後我還有一些提示
一、 儘量使用安裝成windows服務,這樣性能、穩定性更好;若是前期鏈接數不大也可用winform中啓動
二、 若是終端可選.net,那使用SuperSocket.ClientEngine比本身又從新敲更穩健
三、 心跳包應在終端向服務端發送,服務端響應便可,切勿在服務端向終端發心跳(服務端擁有超時機制,若超時終端重連便可)
四、 若是須要支持WebSocket,參考SuperWebScoket;有的網友直接在WebSocket直接鏈接SuperSocket當即斷開
五、 有的人問怎麼傳JSON,參照本文圖1先把數據轉JSON再轉byte[]放到正文內容部分
六、 作Socket開發,可能常常須要在十進制、十六進制、256進制之間轉換(尤爲是在省流量的僅支持2G網絡的硬件)
七、若是你在作硬件開發,你所處的電腦又沒有外網IP,可以使用ngrok反向代理TCP,讓別人代理訪問你的電腦
有關其餘協議或介紹請參考官方文檔
http://docs.supersocket.net/v1-6/zh-CN
有關客戶端或本例子代碼(可直接運行),若是你想先運行看看結果,再本身敲一遍
連接: https://pan.baidu.com/s/1hs09vb2 密碼: 4ntg