基於長鏈接簡單聊天

1、由來

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

做爲研究學習記錄,對簡單長鏈接作一番記錄。github

2、實現原理

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

3、實例

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

服務端主要實現邏輯:ajax

 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的調用

具體效果:api

1.Web客戶,爲了方便通訊,先實現簡單登陸帳號操做微信

2.Web登陸後效果,簡單選擇接收用戶,實現發送及接收。在此,爲了簡單起見,以0用戶做爲羣聊標識網絡

3.Win端簡單按照web端邏輯,展現不一樣,實現差很少架構

4.Win及Web端通訊框架

5.Android端簡單登陸異步

6.實現的三端通訊效果

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

源代碼:見github

相關文章
相關標籤/搜索