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