網站首頁 編程語言 正文
關于WebSocket其實很早就想發了,奈何之前項目中的WebSocket的后端不是我做的,而我又想前后端都發出來和大家討論討論~于是擠出點時間研究了一下WebSocket的后端實現(所以才有了這篇文章)。
首先是概念導論,現在大家在百度、谷歌很容易就能搜索到一大堆這樣的socket(百度百科)、Socket詳解(太多了就不一一列舉)
看過這些概念導論以后,我們準備先實現WebSocket的服務端(基礎概念都沒掌握的童鞋們需要補課了)。
說到.net的WebSocket實現,就不得不說SuperSocket,你可以點擊這里了解和下載它。
看過上面鏈接以后,你應該知道它是有多好用的工具,接下來我們就可以搭建我們的WebSocketServer了:
首先,創建一個窗體應用程序(winForm),當然你也可以創建控制臺應用程序。
然后,需要將下載好的這幾個DLL引入你的項目中:SuperSocket.Common、SuperSocket.SocketBase、SuperSocket.SocketEngine、SuperWebSocket、log4net
其中SuperSocket相關類庫版本為1.6,SuperWebSocket版本為0.9,log4net為1.2(版本錯誤可能會出一些誰也看不懂的碧油雞)。
接下來,我們需要聲明一個webSocket對象,并且給它綁定好事件,比如這樣:
WebSocketServer ws = new WebSocketServer(); ws.NewMessageReceived += Ws_NewMessageReceived;//當有信息傳入時 ws.NewSessionConnected += Ws_NewSessionConnected;//當有用戶連入時 ws.SessionClosed += Ws_SessionClosed;//當有用戶退出時 ws.NewDataReceived += Ws_NewDataReceived;//當有數據傳入時 if (ws.Setup(10086))//綁定端口 ws.Start();//啟動服務
注釋標注的應該清楚,不過這里我沒有對傳入數據做操作,各位看官可以忽略不計。
接下來我們應該怎么做呢?答案是重寫生成的事件方法。很容易看出我們要先處理用戶連入和退出,并且保存和移除用戶信息(不然你都不知道你在和誰聊天),比如這樣:
Dictionary<WebSocketSession, string> userlist = new Dictionary<WebSocketSession, string>();//用戶列表
眼尖的同學們一定發現了一個新類型:WebSocketSession,它是做什么的呢?F12進去以后是這樣的:
貌似什么都沒有?別急,我們再看它的父類:
到這里很多人就明白了,關于連入用戶的諸多信息都在這個類內,還提供了Send方法以便于Server端與之通訊。
搞明白WebSocketSession類型能做什么以后,就可以針對不同操作進行響應了
客戶端在連入服務端時,需要發送一串信息來告訴服務端“who i am”,這時就需要動用Ws_NewMessageReceived事件的方法。
如:客戶端連入時,向服務端發送了“{'user':'001號學生','active':'login'}”,那么我們就可以在服務端將該用戶的信息存儲至上面定義好的userlist中:
//添加至用戶集合的方法 public void AddUser(string UserName, WebSocketSession session) { userList.Add(session, UserName); } //login對應封裝dic方法 public Dictionary<string, string> login(Dictionary<string, string> Query, T curUser) { UserConnHandle userConn = () => { return Query["userid"]; }; Dictionary<string, string> Respon = new Dictionary<string, string>(); if (!service.userList.ContainsKey(curUser)) { if (Query["user"] == "" || Query["user"] == null) { Respon.Add("user", Guid.NewGuid().ToString().Replace("-", "")); } else { Respon.Add("userid", Query["userid"]); } Respon.Add("type", "1");//為了前端更容易操作 Respon.Add("send", "0");//這里0是告訴發給所有用戶還是當前用戶 service.AddUser(Respon["user"], curUser);//將當前用戶添加至用戶集合 } return Respon; } //有新消息傳入時 private void Ws_NewMessageReceived(WebSocketSession session, string value) { Dictionary<string, string> res = login(value, session, this) as Dictionary<string, string>; switch (res["send"]) { case "0": res.Remove("send"); Send(res);//全部發送 break; case "1": res.Remove("send"); string username = res["to"]; WebSocketSession keys = userlist.Where(q => q.Value == username).Select(q => q.Key).First(); SendTo(keys, res);//針對發送 break; } }
這里我封裝成dic只是為了簡單調用,大家不習慣可以封裝成別的(比如List<T>),下面是Send和SendTo:
//發送給所有用戶 public void Send(string msg) { foreach (var item in userList) { item.Key.Send(msg); } } //發送給單個用戶 public void SendTo(WebSocketSession session, string msg) { session.Send(msg); }
其實公聊就是給所有的連入用戶做個遍歷廣播,而私聊只需要針對某用戶廣播即可。
至此,基于SuperSocket實現的WebSocketServer就已經被簡單實現了。
本文中并沒有抽出接口,也沒有做IOC(實際項目上我是做了的),因為這樣寫大家更容易理解,后面的架構優化大家可以自行發揮~
原文鏈接:https://www.cnblogs.com/muchengqingxin/p/6043288.html
相關推薦
- 2022-10-30 C++中線程池ThreadPool源碼解析_C 語言
- 2022-08-07 C++從文件中提取英文單詞的實現方法_C 語言
- 2023-01-07 Python中sys.argv用法圖文詳解_python
- 2021-12-31 linux下RPM包安裝基于xinetd的服務的管理_Linux
- 2022-08-06 WinForm項目中添加幫助文檔功能_C#教程
- 2023-02-17 Golang實踐指南之獲取目錄文件列表_Golang
- 2022-07-12 使用docker搭建Redis-cluster偽集群
- 2022-11-29 C#中各種泛型集合的使用方法總結_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支