1. 程式人生 > >基於長連接簡單聊天

基於長連接簡單聊天

androi res 架構 自定義 代碼 win git http send

一、由來

  最近,公司需要一個即時聊天功能。為此,曾嘗試SignalR,Tencent Mars,重點研究了下mars項目,該項目支持Android,iOS端通信,並能對網絡進行優化處理,是微信內部運行架構。服務端是基於Netty框架通信,數據通過protobuf封裝,並自定義了一套通信協議。客戶端通信,通過封裝好的類庫進行調用。因此,對於項目較急的,上線快速,此方案研究耗時較長,不滿足現狀。因此,在此先試用簡單長連接,並設置好接口,以備後續直接切換成成熟框架。

作為研究學習記錄,對簡單長連接做一番記錄。

二、實現原理

  客戶端發起請求,當有可用消息時,直接返回所請求的消息。如果沒有可用消息,則等待30秒。請求超時後,繼續發起請求。

三、實例

1.服務端,主要基於.net core api,實現Send(發送消息),Receive(接收消息)業務

服務端主要實現邏輯:

 1 [HttpPost]
 2 public IActionResult Send([FromBody] Message message)
 3 {
 4     if (message == null)
 5         return Content("");
 9     lock (_messages)
10     {
11         _messages.Add(new Message
12         {
13             QueueID = _messages.Count > 0
? _messages.Max(q => q.QueueID) + 1 : 1, 14 From = message.From, 15 FromName = _users.FirstOrDefault(u => u.Id == message.From).UserName, 16 To = message.To, 17 ToName = _users.FirstOrDefault(u => u.Id == message.To).UserName, 18 Content = message.Content
19 }); 20 } 21 return Content(""); 22 } 23 24 public IActionResult Receive(long userId, long queueId) 25 { 26 Message retMsg = null; 27 int seconds = 0; 28 do 29 { 30 lock (_messages) 31 { 32 retMsg = _messages.Where(m => (m.To == userId || m.To == 0) && m.From != userId && queueId < m.QueueID).FirstOrDefault(); 33 } 34 if (retMsg == null) 35 { 36 Thread.Sleep(1000); // 5s 37 seconds += 1; 38 } 39 } while (retMsg == null && seconds < 30); 40 return Json(retMsg); 41 }

2.Web客戶端,封裝對服務端Send,Receive的調用,並基於Web展示,ajax異步接收

3.Win客戶端,封裝對服務端Send,Receive的調用

4.Android客戶端,封裝對服務端Send,Receive的調用

具體效果:

1.Web客戶,為了方便通信,先實現簡單登錄賬號操作

技術分享

2.Web登錄後效果,簡單選擇接收用戶,實現發送及接收。在此,為了簡單起見,以0用戶作為群聊標識

技術分享

3.Win端簡單按照web端邏輯,展示不同,實現差不多

技術分享

4.Win及Web端通信

技術分享

技術分享

5.Android端簡單登錄

技術分享

6.實現的三端通信效果

技術分享

技術分享

作為簡單示例,重在實現。而對界面只做了簡單顯示。

源代碼:見github

基於長連接簡單聊天