.NET下使用socket.io随笔记录
一、問題背景
目前公司在互聯(lián)網(wǎng)產(chǎn)品上需要程序與前端部分要進(jìn)行一個(gè)實(shí)時(shí)交互,在進(jìn)行一定程度上的選型后,決定使用socket.io框架進(jìn)行一個(gè)實(shí)踐,算是公司的一個(gè)新的 嘗試,也算是給自己增加增長見聞,由于我是做后端以及桌面程序開發(fā),所以前端部分就不細(xì)聊,主要是針對桌面程序如何連接socket.io進(jìn)行一個(gè)嘗試
二、基本邏輯圖
本地應(yīng)用程序:部署在局域網(wǎng)內(nèi)(可以聯(lián)通外網(wǎng)),主要負(fù)責(zé)相關(guān)數(shù)據(jù)獲取
Web瀏覽器端:跟本地應(yīng)用程序不是處于同一個(gè)網(wǎng)絡(luò),請求發(fā)起方
中轉(zhuǎn)服務(wù)(重點(diǎn)):中轉(zhuǎn)服務(wù)集成認(rèn)證功能,必須經(jīng)過認(rèn)證的客戶端才允許進(jìn)行連接,并且對于客戶端要有唯一指定的ID進(jìn)行連接操作
整體思路如以上的流程圖,由Web瀏覽器端開始發(fā)起請求,Web瀏覽器端通過連接中轉(zhuǎn)服務(wù),將信息發(fā)送給指定的本地應(yīng)用程序,應(yīng)用程序處理完成后,將結(jié)果通過原路徑進(jìn)行一個(gè)反饋
二、客戶端程序開發(fā)
客戶端SDK采用SocketIoClientDotNet,這是一個(gè)github上開源的,可以連接socket.io的客戶端,支持.net 3.5及以上,可以方便的幫助我們進(jìn)行連接socket.io的開發(fā)
Socket? socket = IO.Socket("ws://192.168.7.4:3000", new IO.Options()
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Reconnection = true,
? ? ? ? ? ? ? ?Cookies = new Dictionary<string, string>() { { "companyId", GlobalStatic.COMPANY.COMPANY_ID }, { "userId", GlobalStatic.UserDomain.user.USER_ID } },
? ? ? ? ? ? ? ?Timeout = 60000,
? ? ? ? ? ? ? ?ReconnectionDelay = 1000,
?
? ? ? ? ? ? ? ?Transports = new List<string>() { "websocket" },
? ? ? ? ? ? ? ?Path ="heart"
? ? ? ? ? ?});
?
? ? ? ? ? ?socket.On(Socket.EVENT_CONNECT, () =>
? ? ? ? ? ?{
?
? ? ? ? ? ? ? ?JObject jObject = JObject.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(new
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?companyId = GlobalStatic.COMPANY.COMPANY_ID,
? ? ? ? ? ? ? ? ? ?token = GlobalStatic.TOKEN,
? ? ? ? ? ? ? ? ? ?hostId = GlobalStatic.HOST_ID,
? ? ? ? ? ? ? ? ? ?hostName = GlobalStatic.HOST_NAME,
? ? ? ? ? ? ? ? ? ?printerNames = GlobalStatic.HOSTINFO.PrinterName,
? ? ? ? ? ? ? ? ? ?source = "assistant",
? ? ? ? ? ? ? ? ? ?userId = GlobalStatic.UserDomain.user.USER_ID
? ? ? ? ? ? ? ?}));
? ? ? ? ? ? ? ?socket.Emit("authentication", jObject);
? ? ? ? ? ? ? ?Debug.WriteLine("authentication");
? ? ? ? ? ?});
? ? ? ? ? ?socket.On(Socket.EVENT_DISCONNECT, (data) =>
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Debug.WriteLine("心跳斷開連接" + data);
? ? ? ? ? ? ? ?flag = false;
? ? ? ? ? ? ? ?OnConnectionStatus?.Invoke(flag);
? ? ? ? ? ? ? ?socket.Disconnect();
? ? ? ? ? ?});
? ? ? ? ? ?socket.On("authenticated", (obj) =>
? ? ? ? ? ?{
? ? ? ? ? ? ? ?flag = true;
? ? ? ? ? ? ? ?OnConnectionStatus?.Invoke(flag);
? ? ? ? ? ? ? ?Debug.WriteLine("心跳認(rèn)證成功:" + obj);
? ? ? ? ? ?});
? ? ? ? ? ?socket.On("unauthorized", (obj) =>
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Debug.WriteLine("心跳認(rèn)證失敗" + obj);
? ? ? ? ? ? ? ?socket.Disconnect();
? ? ? ? ? ?});
SocketIoClientDotNet注意點(diǎn):
emit的數(shù)據(jù)必須為字符串或者JObject(Newtonsoft.Json中的)
從實(shí)際情況來看,內(nèi)部每個(gè)On的監(jiān)聽都是維護(hù)了一個(gè)線程,所有如果是不想要阻塞的話,那在on的方法中還需要自己起線程去完成
如果不在options中設(shè)置AutoConnect=false的話,那實(shí)例化socket成功之后就會進(jìn)行connect動作
三、關(guān)于SocketIoClientDotNet坑的問題
在實(shí)際的使用過程中,偶然發(fā)現(xiàn)在程序開了很久 之后,線程數(shù)會一直增多,嘗試調(diào)節(jié)各種參數(shù)都毫無作用,最后只能無奈的跟蹤源碼部分,在Thread文件夾下找到Heartbeat_net35.cs文件中,發(fā)現(xiàn)run方法里的while一直無法跳出去,并且注冊DoWork越來越多,如下所示,導(dǎo)致線程越來越多,目前解決辦法是將該代碼注釋掉,還沒發(fā)現(xiàn)什么問題,如果有哪位知道這段代碼作用的話,望告知,謝謝
using System;
using System.ComponentModel;
using System.Threading;
?
namespace Quobject.EngineIoClientDotNet.Thread
{
? ? public class Heartbeat
? ? {
? ? ? ? private volatile bool gotHeartbeat = false;
? ? ? ? private BackgroundWorker heartBeatTimer= new BackgroundWorker();
? ? ? ? private CancellationTokenSource ts;
?
? ? ? ? private Heartbeat()
? ? ? ? {
? ? ? ? ? ? ts = new CancellationTokenSource();
? ? ? ? }
?
? ? ? ? public static Heartbeat Start(Action onTimeout, int timeout)
? ? ? ? {
? ? ? ? ? ? Heartbeat heartbeat = new Heartbeat();
? ? ? ? ? ? heartbeat.Run(onTimeout, timeout);
? ? ? ? ? ? return heartbeat;? ? ? ? ? ?
? ? ? ? }
?
? ? ? ? public void OnHeartbeat()
? ? ? ? {
? ? ? ? ? ? gotHeartbeat = true;
? ? ? ? }
?
? ? ? ? private void Run(Action onTimeout, int timeout)
? ? ? ? {
? ? ? ? ? ? heartBeatTimer = new BackgroundWorker();
?
? ? ? ? ? ? heartBeatTimer.DoWork += (s, e) =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ?while (!ts.IsCancellationRequested)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? System.Threading.Thread.Sleep(timeout);
? ? ? ? ? ? ? ? ? ? if (!gotHeartbeat && !ts.IsCancellationRequested)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? onTimeout();
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
?
? ? ? ? ? ? heartBeatTimer.RunWorkerAsync();
? ? ? ? }
?
? ? ? ? public void Stop()
? ? ? ? {
? ? ? ? ? ? ts.Cancel();
? ? ? ? }
? ? }
}
原文地址: http://www.cnblogs.com/OMango/p/8443395.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的.NET下使用socket.io随笔记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core使用swagger进行
- 下一篇: 超级简便的容器化部署工具(使用 ASP.