使用SuperSocket打造逾10万长连接的Socket服务
SuperSocket 是一個(gè)輕量級, 跨平臺而且可擴(kuò)展的 .Net/Mono Socket 服務(wù)器程序框架。你無須了解如何使用 Socket, 如何維護(hù) Socket 連接和 Socket 如何工作,但是你卻可以使用 SuperSocket 很容易的開發(fā)出一款 Socket 服務(wù)器端軟件,例如游戲服務(wù)器,GPS 服務(wù)器, 工業(yè)控制服務(wù)和數(shù)據(jù)采集服務(wù)器等等。
?
PS:上面這句話復(fù)制官網(wǎng)的,好了,總之告訴大家SuperSocket已經(jīng)很強(qiáng)大、很穩(wěn)定、方便。
如果你沒有Socket基礎(chǔ),首先要了解協(xié)議;本人兩年都在做智能穿戴,接觸大量硬件廠商,發(fā)現(xiàn)大部分是“帶起止符的協(xié)議”(BeginEndMarkReceiveFilter)或者“頭部格式固定并且包含內(nèi)容長度的協(xié)議”(FixedHeaderReceiveFilter)
?
我簡單介紹這兩種協(xié)議。
代碼上我就二選一介紹FixedHeaderReceiveFilter吧
首先新建項(xiàng)目,在Nuget管理器上搜索“SuperSocket”安裝“SuperSocket”和“SuperSocket.Engine”
?
?
接下來你需要實(shí)現(xiàn)
1、 IRequestInfo(請求信息,一次數(shù)據(jù)包)
public class MyRequestInfo : IRequestInfo{public MyRequestInfo(byte[] header, byte[] bodyBuffer){Key = ((header[0] * 256) + header[1]).ToString();Data = bodyBuffer;}/// <summary>/// 協(xié)議號對應(yīng)自定義命令Name,會觸摸自定義命令/// </summary>public string Key { get; set; }/// <summary>/// 正文字節(jié)碼/// </summary>public byte[] Data { get; set; }/// <summary>/// 正文文本,大部分協(xié)議都不是這么玩的/// </summary>public string Body{get{return Encoding.UTF8.GetString(Data);}}}2、 FixedHeaderReceiveFilter<IRequestInfo>(數(shù)據(jù)包的解析)
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);}}3、 AppSession<TAppSession, TRequestInfo>(Session會話,服務(wù)端管理客戶端的連接、信息)
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);}}4、 AppServer<TAppSession, TRequestInfo>(監(jiān)聽服務(wù))
public class MyServer : AppServer<MySession, MyRequestInfo>{/// <summary>/// 通過配置文件安裝服務(wù)從這里啟動/// </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秒執(zhí)行一次清理90秒沒數(shù)據(jù)傳送的連接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}啟動失敗,請檢查權(quán)限或端口是否被占用!", config.Ip, config.Port));}?
有關(guān)性能,本人在本地(筆記本i5 4200H/12G)測試10萬連接同時(shí)在線,沒有問題;當(dāng)然啦,跟業(yè)務(wù)有關(guān),比如你要做的是IM群聊,數(shù)據(jù)到服務(wù)端需要頻繁計(jì)算。
?
最后我還有一些提示
1、 盡可能使用安裝成windows服務(wù),這樣性能、穩(wěn)定性更好;如果前期連接數(shù)不大也可用winform中啟動
2、 如果終端可選.net,那使用SuperSocket.ClientEngine比自己又重新敲更穩(wěn)健
3、 心跳包應(yīng)在終端向服務(wù)端發(fā)送,服務(wù)端響應(yīng)即可,切勿在服務(wù)端向終端發(fā)心跳(服務(wù)端擁有超時(shí)機(jī)制,若超時(shí)終端重連即可)
4、 如果需要支持WebSocket,參考SuperWebScoket;有的網(wǎng)友直接在WebSocket直接連接SuperSocket立即斷開
5、 有的人問怎么傳JSON,參照本文圖1先把數(shù)據(jù)轉(zhuǎn)JSON再轉(zhuǎn)byte[]放到正文內(nèi)容部分
6、 做Socket開發(fā),可能經(jīng)常需要在十進(jìn)制、十六進(jìn)制、256進(jìn)制之間轉(zhuǎn)換(尤其是在省流量的僅支持2G網(wǎng)絡(luò)的硬件)
7、如果你在做硬件開發(fā),你所處的電腦又沒有外網(wǎng)IP,可使用ngrok反向代理TCP,讓別人代理訪問你的電腦
?
有關(guān)其他協(xié)議或介紹請參考官方文檔
http://docs.supersocket.net/v1-6/zh-CN
?
有關(guān)客戶端或本例子代碼(可直接運(yùn)行),如果你想先運(yùn)行看看結(jié)果,再自己敲一遍
鏈接: https://pan.baidu.com/s/1hs09vb2 密碼: 4ntg
?
posted on 2018-06-14 02:47 NET未來之路 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/9181132.html
總結(jié)
以上是生活随笔為你收集整理的使用SuperSocket打造逾10万长连接的Socket服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue项目条形码和二维码生成工具试用
- 下一篇: Bing Speech Recognit