蘇成武



摘要:本文針對網絡即時通信IM(Instant Messenger)存在的多渠道(不同瀏覽器、不同客戶端)、多協議(HTTP、Flash XMLSocekt、WebSocket)接入困難問題,設計了一個多模融合即時消息服務,使各業務系統以統一的接口接入各渠道及各協議,同時可以不在修改業務系統的前提下接入新的渠道及協議。實踐運行表明,本系統具有良好的易用性和可擴展性,已在多個業務系統推廣使用。
關鍵詞:IM;網絡即時通信;即時消息服務
中圖分類號:TP393? ? ? 文獻標識碼:A
文章編號:1009-3044(2022)12-0035-03
開放科學(資源服務)標識碼(OSID):
隨著移動互聯網的發展,用戶利用手機、電腦上網的時間越來越多,以“社區(Community)” “內容(Contenet)”“商務(Commerce)”為主要特征的網絡即時通信IM(Instant Messenger),越來越受到用戶的重視。網絡即時通信使得用戶的溝通更加方便、快捷,使用戶真正有了天涯若比鄰的“地球村”的感覺。
用戶可通過瀏覽器(IE、Chrome、Firefox、Safari、Edge)、Windows桌面軟件、Linux桌面軟件、MAC桌面軟件、安卓App、蘋果App等不同的渠道訪問業務系統。由于歷史原因,各渠道實現網絡即時通訊的技術差異較大,如Chrome、Firefox、Safari、Edge等較新的瀏覽器支持HTML5標準中的WebSocket,可通過WebSocket實現網絡即時通訊。較老版本的IE瀏覽器只能通過輪詢方式或Flash XMLSocekt實現即時通訊。而Windows桌面軟件、Linux桌面軟件、MAC桌面軟件、安卓App、蘋果App等需要通過Socket實現網絡即時通訊。如果業務系統負責每一個渠道的網絡即時通訊接入,無疑會導致業務系統過于復雜,不利于不同業務系統之間代碼共享,同時增加新的協議接入時,會破壞原有的業務系統。
基于以上的問題,本文提出了一種多模融合技術的即時通訊解決方案,建立一個多模融合即時消息服務,接收不同渠道的客戶端連接,并從連接當中取出一定數量的字符,與各對應的協議報文頭進行字符匹配,從而識別連接渠道客戶端所使用的協議,并按協議格式解析報文數據。再通過統一的協議與業務系統進行通訊,并將解析出的數據傳遞給業務系統進行處理,并可將業務系統返回的結果推送給各渠道的客戶端。通過多模融合即時消息服務可實現與業務系統的統一通訊,即使增加新的渠道客戶端協議,只用修改多模融合即時消息服務,實現了業務與即時消息能力的解耦。當連接海量用戶時,只需部署多套模融合即時消息服務即可。
1 主要內容
基于EPOLL技術實現高性能的多模融合即時消息服務,通過此服務,可以實現不同渠道不同協議的接入,并為后臺業務系統提供統一的接口??梢越档蜆I務系統代碼的復雜度,并可實現不同業務系統即時消息的功能復用。
本解決方案的內容主要分為以下幾個方面:
1)協議識別器:通過關鍵字符的匹配,識別出當前渠道客戶端所采用的協議,為后續的數據處理和結果返回提供必要的信息,本設計可自動識別出HTTP、Flash XMLSocekt、WebSocket等協議。
2)協議解碼器:實現HTTP、Flash XMLSocekt、WebSocket等協議的解碼器,從傳輸協議里面解析出數據報文供下一步處理。
3)協議編碼器:實現HTTP、Flash XMLSocekt、WebSocket等協議的編碼器,將業務系統或心跳包等模塊返回的結果數據按相應的協議封裝并返回給渠道客戶端。
4)多模融合框架:開發統一的多模融合框架,進行服務端口監聽并處理網絡事件(采用EPOLL實現高性能網絡事件處理)。同時提供統一的接口,可支持不同的協議識別器、協議解碼器、協議編碼器接入多模融合框架。
5)心跳檢測:通過定時向渠道客戶端和業務系統發送心跳包,可剔除已經異常斷開的連接,保證連接的有效性。
6)開放SDK:向業務系統和渠道客戶端提供建立連接、獲取數據、發送數據、斷開連接等接口。
2 總體架構設計
渠道客戶端集成開放SDK,向多模融合即時消息服務發起連接請求并攜帶報文數據。多模融合即時消息服務的多模融合框架收到報文后調用協議識別器,識別出渠道客戶端所使用協議。將協議報文傳給相應的解碼器進行解碼,解碼出的數據通過多模融合框架傳輸給業務系統并接收業務系統返回的數據,經過協議編碼器編碼后將數據返回給渠道客戶端。同時多模融合即時消息服務通過心跳檢測模塊檢測,定時向渠道客戶端和業務系統發送心跳包以檢測其是否存活。
3 各模塊詳細設計
3.1 多模融合框架設計
多模融合即時消息服務在啟動時調用多模融合框架進行初始化。多模融合框架讀取配置文件,并監聽配置文件配置的網絡端口,再通過EPOLL事件驅動機制實現與渠道客戶端及業務系統的網絡通訊。同時初始化一個哈希表,用于協議解碼器和協議編碼器的注冊,以便識別出協議后可以快速查找到解碼器和編碼器并對網絡報文進行編碼和解碼,編解碼器需一一對應,一個解碼器只對應且必須對應一個編碼器。
3.1.1 EPOLL事件驅動機制
EPOLL是Linux提供的高性能網絡事件驅動機制,可以使應用程序支持海量的用戶接入。EPOLL是在SELECT事件驅動機制上發展而來,SELECT事件驅動機制需程序每次將所有待監聽的SOCKET傳入內核,內核在某一SOCKET出現讀、寫、關閉等事件時,再將事件返回給應用程序,應用程序再通過遍歷所有SOCKET來判斷是否發生相關的事件。應用程序每一輪處理,都要向內核傳遞所有SOCKET,同時發生事件時要遍歷所有的SOCKET,性能較低。而EPOLL則當有新的SOCKET時才告知內核需監聽此SOCKET,同時有讀、寫、關閉等事件時內核只會將發生事件的SOCKET通知應用程序,從而減少內核與應用程序的數據交換及SOCKET的遍歷,支持海量用戶接入[1]。
3.1.2 哈希表
哈希表是一種數據結構,存儲KEY-VALUE值。通過哈希函數將KEY值映射成長整型的HASHCODE,將此HASHCODE作為VALUE值存儲的位置(數組索引),當不同KEY值映射到同一個存儲位置時,通過雙向鏈表來存儲VALUE值。只要哈希函數合理,在KEY值分布較稀疏的情況下,哈希表有較好的查詢性能(O(1)的時間復雜度),通過哈希函數可以一次定位到對應的VALUE值[5]。
3.2 協議識別器設計
協議識別器是多模融合即時消息服務核心組件,只有準確識別出渠道客戶端所使用的協議,才能進行下一步處理。協議識別器在有渠道客戶端進行連接并接收第一個報文數據時,通過分析報文頭部數據的關鍵字符并根據核心邏輯識別出對應的協議,并解析報文頭的數據(如HTTP頭部)與當前渠道客戶端連接進行關聯,為下一步處理做好充分準備。下表列出了識別HTTP、Flash XMLSocekt、WebSocket三種不同協議報文頭部關鍵字符和核心邏輯。
3.3 解碼器和編碼器設計
解碼器和編碼器需一一對應,即一個解碼器只對應且必須對應一個編碼器,因此解碼器和編碼器應在一起設計。解碼器其核心內容根據協議格式解碼出實際傳輸的數據供業務系統使用,編碼器的作用主要是將業務系統返回結果按協議格式進行封裝并返回給渠道客戶端。
3.3.1 HTTP解碼器/編碼器設計
HTTP解碼器/編碼器基于HTTP協議[3]進行了擴展,改變HTTP協議的一問一答形式,雙方均可以隨時通過HTTP請求或響應報文發送數據給對方。渠道客戶端發送信息時使用HTTP請求報文(解碼器),多模融合即時消息服務返回消息時使用HTTP響應報文(編碼器)。
1)解碼器報文
請求行:發送post請求并指明使用http1.1版本。
請求頭部:第二行至第六行攜帶相應的頭部,如標注報文長度等。
空行:請求頭部和請求數據之間的間隙。
請求數據:即時通訊攜帶的報文數據。
2)編碼器報文
狀態行:指明HTTP協議版本號及狀態碼、狀態消息,如上例中HTTP版本為1.1,狀態碼為200,狀態消息為(ok)。
消息報頭:攜帶客戶端要使用的一些附加信息。
空行:消息報頭與響應正文后面的空行是必須的。
響應正文:服務器返回給客戶端的文本信息,空行后面的html部分為響應正文。
3.3.2 Flash XMLSocekt解碼器/編碼器設計
Flash XMLSocekt在建立連接后第一個數據報文發送前,需進行沙箱和安全策略認證。具體為Flash建立連接后發送一個字符串,內容為 "
在通過沙箱和安全策略認證后,每一個請求報文首先發送兩個字節的報文長度,接下來的字節即為報文數據,具體報文格式由各業務系統自行定義(解碼器和編碼器發送的數據報文格式完全一致,只是發送的方向不一樣)。下圖為有兩個數據報文的示例:
3.3.3 WebSocekt解碼器/編碼器設計
按照RFC標準,WebSocket的建立需要借助于HTTP,其流程為:渠道客戶端發一個HTTP GET請求(這個請求只包含一些頭部)攜帶升級為WebSocket的頭部[4]標識到服務端,服務端確認后,渠道客戶端與服務端就可以按WebSocket消息幀(WebSocekt解碼器和編碼器均按此消息幀格式封裝通信)進行通信。
3.4 心跳檢測設計
多模融合即時消息服務定時向渠道客戶端和業務系統發送心跳包報文,如果規定的時間內(可通過配置文件配置)收到渠道客戶端或業務系統的回復報文,則認為連接正常,否則從連接信息清單里剔除無效的連接。具體做法為當渠道客戶端或業務系統建立連接成功后,多模融合即時消息服務為每一個渠道客戶端或業務系統建立連接信息,并初始化一個字段最后讀寫時間為當前時間,在后續收到或發送數據時均更新最后讀寫時間字段。同時多模融合即時消息服務建立系統定時任務,每隔5秒鐘遍歷一次連接信息,當某一個連接最后讀寫時間超過一定的時長后,則發送心跳包報文。
3.5 開放SDK設計
開放SDK主要功能是為渠道客戶端和業務系統提供接入多模融合即時消息服務并進行相關接口功能API的調用。為渠道客戶端主要提供C、JAVA、JavaScript、Flash等不同語言版本。為業務系統主要提供C、JAVA等不同語言版本。主要接口清單如下:
1)連接建立:與多模融合即時消息服務進行連接,需輸入參數業務系統標識、渠道客戶端ID、服務URL,輸出結果為連接是否成功、當前連接TOKEN、連接結果描述。
2)發送數據:通過多模融合即時消息服務向業務系統或另一個渠道客戶端發送數據,需要輸入對端標識(業務系統標識或連接TOKEN)、數據(JSON字符串),輸出結果為是否發送成功。
3)接收數據:通過回調方法的行式向渠道客戶端返回接收到的JSON字符串,具體JSON里面的字段按業務需要進行定制。
4)斷開連接:斷開與多模融合即時消息服務的連接,需輸入的參數為當前連接TOKEN,輸出結果為空。斷開連接后此連接將釋放不可用。
4 結語
本文主要針對網絡即時通信的多渠道(不同瀏覽器、不同客戶端)、多協議(HTTP、Flash XMLSocekt、WebSocket)的統一接入進行分析和設計。采用EPOLL事件驅動機制實現高性能網絡即時通信,同時基于哈希表的數據結構實現了不同協議的解碼器及解碼器的接入,保證平臺的松耦合性、高可靠性和后期可維護性。本文針對目前網絡即時通信的痛點(多渠道、多協議接入工作量大,耗時長)進行了分析,并且這些痛點在本設計的系統中得到了有效的解決與改善。現階段基本上達到了設計目標,實現了多模融合即時消息服務的主要內容。同時本系統在實時性、可用性、易用性等方面都達到了良好的效果,在一定程度上解決了各業務系統接入即時通信的工作量大,耗時長,等諸多痛點。本系統可以較為明顯地為各業務系統進行服務,節省開發人員的時間和精力,可以在一定程度上推動網絡即時通信的變革。
參考文獻:
[1] WarrenW Gay.實戰Linux Socket 編程[M].詹俊鵠,譯.西安:西安電子科技大學出版社,2002.
[2] [加拿大]班得遜.Adobe Flex 3高級編程[M].北京:清華大學出版社,2011.
[3] David Gourley,Brian Totty.HTTP權威指南[M].陳涓,趙振平,譯.北京:人民郵電出版社,2012.
[4] 齊華,李佳,劉軍.基于Websocket的消息實時推送設計與實現[J].微處理機,2016,37(3):36-39,43.
[5] 嚴蔚敏,吳偉民.數據結構[M].北京:清華大學出版社,1997.
【通聯編輯:張薇】