基於長連接簡單聊天
阿新 • • 發佈:2017-08-01
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.Content19 }); 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
基於長連接簡單聊天