唐 超
(湖北開放大學(xué),湖北 武漢 430074)
近年來,隨著“互聯(lián)網(wǎng)+”的廣泛應(yīng)用和人工智能技術(shù)的快速發(fā)展,信息化教學(xué)的改革步伐也呈現(xiàn)加速趨勢。教學(xué)答疑工具既是教師沉淀學(xué)情數(shù)據(jù)的重要依賴,又是課堂外輔導(dǎo)學(xué)生學(xué)習(xí)的有力工具。當(dāng)前,基于瀏覽器-服務(wù)器模式(簡稱“BS模式”),絕大多數(shù)教學(xué)答疑工具被設(shè)計成留言板的形式,同時嵌入了教學(xué)案例資源庫,但并未包含即時通信功能。調(diào)研顯示學(xué)生使用答疑工具自帶的案例庫雖能解決學(xué)習(xí)時遇到的部分問題,但在使用過程中依然缺乏師生即時教學(xué)互動或集體討論的功能。市面上現(xiàn)有的第三方即時通信軟件并未針對學(xué)生使用教學(xué)案例資源庫的場景設(shè)計專項支持,并且對話窗口的聊天數(shù)據(jù)也普遍不提供按需導(dǎo)出的功能,教師分析教研數(shù)據(jù)時會遇到學(xué)情數(shù)據(jù)多點分布的局面,這種情形削弱了學(xué)情分析時的數(shù)據(jù)價值。如何滿足學(xué)生使用案例庫時的即時答疑需求并方便教師更高效全面地沉淀學(xué)情數(shù)據(jù),是加快推進(jìn)信息化教學(xué)改革的重要課題。本文將從解決上述問題的視角出發(fā),利用通信協(xié)議族演進(jìn)的新協(xié)議特性,研究在基于瀏覽器-服務(wù)器模式的教學(xué)答疑工具中增加即時通信功能。
當(dāng)前,不少教學(xué)答疑工具以留言板的形式進(jìn)行師生答疑互動,這種設(shè)計并未考慮師生雙方在課堂外針對教學(xué)知識點交流時的即時互動需求。留言板式的溝通形式也不利于教師及時捕獲學(xué)生學(xué)習(xí)的思維片段和思考過程,此外教師在定期整理案例資源時需要再次查找此前使用其他即時通信軟件與學(xué)生交流時的記錄,多點分布的學(xué)情記錄在整理時容易被遺漏,制約了案例整理的效率和質(zhì)量。對學(xué)生而言,單純留言板式的教學(xué)答疑工具無法對待解決的問題開展快速溝通,也缺少對問題進(jìn)行集體討論的學(xué)習(xí)體驗。經(jīng)驗表明,不管是線上還是線下形式的即時溝通過程,都能激發(fā)學(xué)生對所學(xué)知識的參與感。
留言板式的Web應(yīng)用選用的是HTTP協(xié)議族,即瀏覽器和服務(wù)器之間的交互依托HTTP或HTTPS協(xié)議溝通,根據(jù)該協(xié)議族的技術(shù)原理,基于瀏覽器-服務(wù)器模式的通信只有將場景限定為客戶端發(fā)送請求至服務(wù)器,服務(wù)器才能回復(fù)客戶端的工作模式。服務(wù)器無法主動推送消息至客戶端,兩者的收發(fā)過程無法割裂,彼此的先后順序也不能調(diào)整。服務(wù)器連接的多個客戶端之間只有需要通過服務(wù)器中間轉(zhuǎn)發(fā),才能實現(xiàn)通信[1]。多客戶端交互結(jié)構(gòu)如圖1所示,如果甲、乙2個瀏覽器客戶端需要相互通信,那么甲需要將攜帶接收者信息的消息發(fā)給服務(wù)器,服務(wù)器根據(jù)甲攜帶的信息將消息傳遞給乙,乙傳遞給甲消息則是反向流程。此外HTTP協(xié)議族的另一特點是服務(wù)端回復(fù)消息至客戶端后,本次連接隨即斷開,下次通信時需要再次建立連接。該協(xié)議的技術(shù)特性無法直接用于即時通信軟件產(chǎn)品的實現(xiàn)。

圖1 多客戶端交互結(jié)構(gòu)
傳統(tǒng)的HTTP協(xié)議若要實現(xiàn)即時通信的效果需要解決以下3個問題。
2.2.1 全雙工通信
瀏覽器能主動從服務(wù)器側(cè)拉取數(shù)據(jù)(pull data),服務(wù)器亦能給瀏覽器主動推送數(shù)據(jù)(push data),推送場景下無需依賴瀏覽器的主動請求就可實現(xiàn)。這2種場景共同組成全雙工通信模式。
2.2.2 低延時感知
無論是瀏覽器拉取數(shù)據(jù),還是服務(wù)端推送數(shù)據(jù),整個環(huán)節(jié)需要保持在延時很低的水平,量化標(biāo)準(zhǔn)是以用戶在界面操作時對產(chǎn)生的延時無感知。
2.2.3 多端間跨域
當(dāng)瀏覽器和服務(wù)器之間存在協(xié)議、域名、主機號、端口號等任意構(gòu)成訪問地址的要素不相同時,二者之間依然可以相互通信,確保實現(xiàn)跨域通信的功能。
2.3.1 短輪詢
瀏覽器利用異步請求(Asynchronous Javascript And XML,AJAX)的特點,設(shè)置在較短的時間間隔內(nèi)連續(xù)向服務(wù)端發(fā)送請求,依據(jù)服務(wù)器返回的結(jié)果對頁面局部內(nèi)容刷新,變相實現(xiàn)即時通信的效果。這種方案雖然在代碼層面相對簡易,但高頻請求會增加服務(wù)器的開銷,消耗網(wǎng)絡(luò)帶寬資源。當(dāng)服務(wù)端數(shù)據(jù)沒有更新時,瀏覽器依然高頻發(fā)送連接請求,在收到服務(wù)端的回復(fù)后又馬上釋放連接,這種高頻建立連接又馬上釋放的操作導(dǎo)致系統(tǒng)效率較低[2]。
2.3.2 長輪詢
這種方案對短輪詢做出算法改進(jìn)。當(dāng)瀏覽器和服務(wù)端建立連接后,若瀏覽器需要的數(shù)據(jù)并未更新,服務(wù)端采用線程阻塞的方式保持連接并監(jiān)視本側(cè)數(shù)據(jù),出現(xiàn)數(shù)據(jù)更新時將更新內(nèi)容返回瀏覽器。當(dāng)服務(wù)端本側(cè)數(shù)據(jù)未更新時,其保持連接直至超時,從而減少了瀏覽器對服務(wù)端的請求頻次。
2.3.3 基于HTTP流
這種方案的原理是瀏覽器和服務(wù)端建立連接后,服務(wù)端并非采用阻塞線程的方式保持連接不斷開,而是不間斷地向瀏覽器發(fā)送HTTP數(shù)據(jù)流,這種持續(xù)數(shù)據(jù)流會對瀏覽器的緩存造成較大的壓力。
2.3.4 服務(wù)器推送事件
服務(wù)器推送事件(Server-sent Events)作為HTML5規(guī)范的子集,雖然能在HTTP和HTTPS協(xié)議上執(zhí)行,但是它僅支持從服務(wù)器往瀏覽器的單向傳輸,不支持全雙工通信。
基于HTTP協(xié)議族的方案本質(zhì)上是運用多組半雙工形式的技術(shù),在方案整體的兼容性和未來的擴展性上均受到了限制,優(yōu)化方案可以使用演進(jìn)的WebSocket協(xié)議搭建全雙工通信模式。
在21世紀(jì)的前十年,關(guān)于HTML的標(biāo)準(zhǔn)一直未能形成統(tǒng)一的協(xié)議規(guī)范。2014年,在微軟、谷歌等全球巨頭的推動下,HTML5協(xié)議正式落地。WebSocket作為HTML5協(xié)議的子集,全球各大瀏覽器、服務(wù)器廠商都以此為標(biāo)準(zhǔn)適配和規(guī)范自己的產(chǎn)品,Oracle公司也在JDK中同步實現(xiàn)了這些協(xié)議。至此,WebSocket在客戶端和服務(wù)端實現(xiàn)了規(guī)則的統(tǒng)一。
WebSocket的實現(xiàn)借鑒了Socket套接字的原理。WebSocket協(xié)議流程如圖2所示。客戶端創(chuàng)建Socket實例并關(guān)聯(lián)遠(yuǎn)端的網(wǎng)絡(luò)地址和端口號,服務(wù)器同步創(chuàng)建Socket實例并綁定監(jiān)聽本地端口。當(dāng)請求被服務(wù)器接受后,兩端間建立起基于傳輸控制協(xié)議(Transmission Control Protocol,TCP)的長連接,形成全雙工通信環(huán)境。此時客戶端和服務(wù)器彼此的角色將呈現(xiàn)趨同化、歸一化的特性。在長連接的環(huán)境下,數(shù)據(jù)以frame序列形式傳輸,顯著降低了網(wǎng)絡(luò)鏈路頻繁斷聯(lián)的開銷,實現(xiàn)歸一化和持久化,有效滿足了全雙工和高并發(fā)場景。WebSocket協(xié)議是為實現(xiàn)Web客戶端與服務(wù)端全雙工通信而專門制定的一種應(yīng)用層協(xié)議,通常表示為ws://echo.websocket.org/?encoding=text HTTP/1.1。協(xié)議格式和URL非常相似,協(xié)議名部分區(qū)別顯著[3]。

圖2 WebSocket協(xié)議流程
反觀HTTP協(xié)議,因缺乏狀態(tài)保存的機制,當(dāng)消息從服務(wù)端返回客戶端后,本次連接隨即斷開,后續(xù)傳輸需重新建立連接。如此反復(fù)將增加網(wǎng)絡(luò)鏈路的斷聯(lián)開銷。HTTP協(xié)議流程如圖3所示。

圖3 HTTP協(xié)議流程
WebSocket協(xié)議作為HTML5協(xié)議的子集,展現(xiàn)出良好的向前兼容特性。圖4是WebSocket協(xié)議建立連接時的收發(fā)報文。RequestMethod字段內(nèi)容代表初次握手時采用GET請求類型。請求頭中Connection字段配置的Upgrade代表客戶端請求服務(wù)端升級現(xiàn)有協(xié)議。Upgrade字段代表準(zhǔn)備升級后將采用的新協(xié)議名字。Sec-WebSocket-Key是客戶端基于Base64加密算法處理后發(fā)送給服務(wù)端的密鑰,要求服務(wù)端返回Sec—WebSocket—Accept字段,否則握手環(huán)節(jié)將失敗,連接過程取消。服務(wù)端返回的響應(yīng)頭內(nèi)對等包含Connection和Upgrade這2個字段,配置的內(nèi)容及含義和請求頭中完全一樣。Sec—WebSocket—Accept字段的配置要求服務(wù)端和客戶端采用相同密鑰進(jìn)行身份可信驗證。在General中,StatusCode配置101狀態(tài)碼,Switching Protocols代表服務(wù)端同意客戶端將協(xié)議從HTTP升級成WebSocket[4-5]。

圖4 WebSocket協(xié)議請求頭和響應(yīng)頭的字段
WebSocket協(xié)議實現(xiàn)了全雙工通信,在Web系統(tǒng)前后端分離的體系設(shè)計中,需在客戶端和服務(wù)端同時實現(xiàn)該協(xié)議。實施的項目采用了網(wǎng)頁瀏覽器形態(tài)的客戶端,JavaScript作為客戶端開發(fā)語言。本地服務(wù)器軟件選用Apache基金會的開源軟件Tomcat,后端選用SpringBoot框架。
3.3.1 服務(wù)端的協(xié)議實現(xiàn)
基于SpringBoot框架的服務(wù)端采用MVC的分層設(shè)計,服務(wù)端軟件按照模塊功能邊界分為Controller、Service、Mapper、domain幾個層級。為了解決WebSocket協(xié)議相關(guān)接口的依賴問題,項目服務(wù)端采用了通過依賴管理工具M(jìn)aven導(dǎo)入spring-boot-starter-WebSocket包予以解決。服務(wù)端側(cè)的工具包Utils中定義的配置類工具負(fù)責(zé)在程序運行期間通過Configuration和Bean注解以控制反轉(zhuǎn)的形式動態(tài)注入一個ServerEndpointExporter類型對象,以便實現(xiàn)項目Controller層級的角色。
在負(fù)責(zé)具體業(yè)務(wù)執(zhí)行的Service層,項目定義了服務(wù)端協(xié)議接口實現(xiàn)類,通過標(biāo)注在類層級上的@ServerEndpoint注解實現(xiàn)對客戶端通過指定URL連接服務(wù)端場景的監(jiān)聽。服務(wù)端協(xié)議引入@OnOpen、@OnClose、@OnMessage、@OnError注解標(biāo)注需要實現(xiàn)的接口方法。根據(jù)協(xié)議,當(dāng)客戶端與服務(wù)端之間的連接建立成功后,服務(wù)端的協(xié)議實現(xiàn)類將調(diào)用onOpen接口。當(dāng)兩端間的網(wǎng)絡(luò)鏈路斷開時,協(xié)議實現(xiàn)類會運行onClose接口。在客戶端的消息到達(dá)服務(wù)端后,服務(wù)端的協(xié)議實現(xiàn)類將執(zhí)行onMessage接口,提取消息的具體內(nèi)容,并根據(jù)消息字段中嵌入的目標(biāo)地址將內(nèi)容直接推送給目標(biāo)客戶端。在推送消息時,為確保執(zhí)行線程安全,程序?qū)nMessage接口的注入?yún)?shù)session對象先在本地創(chuàng)建副本,之后通過引用副本運行BasicRemote屬性的sendText方法完成消息的具體推送。onError接口是服務(wù)端在運行過程中出錯時,協(xié)議實現(xiàn)類將運行的回調(diào)方法,主要實現(xiàn)異常的捕獲和提示輸出。
3.3.2 客戶端的協(xié)議實現(xiàn)
項目選用Vue框架實現(xiàn)網(wǎng)頁形態(tài)的客戶端。程序利用網(wǎng)頁頁面加載完成時調(diào)用生命周期onLoad方法的特點,通過客戶端原型對象變量調(diào)用connectSocket方法實例化WebSocket協(xié)議對象,connectSocket接口依賴的配置類屬性中包含了本次連接對應(yīng)服務(wù)端的地址和端口號。屬性集合中的success鍵名對應(yīng)客戶端和服務(wù)端連接成功后的回調(diào)對象,其攜帶的resConnect鍵名代表服務(wù)端返回的連接成功狀態(tài)。fail鍵名對應(yīng)兩端網(wǎng)絡(luò)鏈路建立失敗后的回調(diào)接口,其攜帶的resConnectError代表了連接失敗后服務(wù)端返回的狀態(tài)對象。當(dāng)瀏覽器和服務(wù)端的網(wǎng)絡(luò)鏈路連接成功后,客戶端原型對象就能繼續(xù)注冊onMessage和onClose接口,客戶端中onMessage、onClose接口方法與服務(wù)端中對應(yīng)的接口方法,以相互鏡像映射的形式實現(xiàn)功能同步。
3.3.3 其他功能實現(xiàn)
(1)數(shù)據(jù)庫處理。
為方便后期挖掘?qū)W情數(shù)據(jù),教輔答疑系統(tǒng)需要持久化存檔客戶端之間的消息記錄,數(shù)據(jù)統(tǒng)一存入數(shù)據(jù)庫。程序?qū)为殨捄腿簳挼挠涗浄謩e作為消息歸檔單元創(chuàng)建表格,表中設(shè)置的字段包括對話內(nèi)容、對話的時間戳、語句發(fā)言人的ID(關(guān)聯(lián)用戶表的外鍵)、語句發(fā)言人的窗口昵稱、會話窗口的ID、消息讀取狀態(tài)、未讀的數(shù)量等關(guān)鍵內(nèi)容。考慮到網(wǎng)頁瀏覽器緩存容量的限制,這些數(shù)據(jù)表統(tǒng)一存放在服務(wù)端。這種設(shè)計既能保證數(shù)據(jù)的相對安全,又能確保不同客戶端加載的歷史消息內(nèi)容的一致性,有利于完整還原并展示不同對話窗口的歷史記錄。
(2)對話窗口內(nèi)容渲染。
當(dāng)前賬號打開對話窗口時,其將在歷史記錄展示面板上渲染最近的對話記錄。對話窗口通過請求向服務(wù)端查詢當(dāng)前會話的歷史對話記錄。在設(shè)置查詢條件時,程序按照距離當(dāng)前時間戳較短的固定時長向前查詢,避免出現(xiàn)因查詢歷史記錄較多而出現(xiàn)頁面長時間等待的情況。對于收到的未讀消息,程序通過觸發(fā)器機制獲取未讀消息的內(nèi)容及數(shù)量,及時在窗口渲染標(biāo)記。為加強對窗口未讀消息的集中管理,服務(wù)端將未讀消息統(tǒng)一添加到單獨的集合中,當(dāng)未讀消息被讀取后,及時更新數(shù)據(jù)表中對應(yīng)的標(biāo)記字段,并同步移出未讀消息集合中的消息節(jié)點。為便于頁面區(qū)分歷史對話記錄的消息來源,在渲染記錄時會根據(jù)記錄來源與當(dāng)前登錄賬號的匹配關(guān)系分別將記錄渲染在界面的左側(cè)或者右側(cè)。
(3)在線好友列表刷新。
在當(dāng)前賬號上線后,程序需在面板加載所有在線用戶。為保持?jǐn)?shù)據(jù)的統(tǒng)一,服務(wù)端代碼設(shè)置一個集合專門存放當(dāng)前在線的用戶賬號,當(dāng)客戶端在與服務(wù)端連接成功后需要遍歷該集合,以便獲取最新的上線賬號信息。客戶端將獲取的當(dāng)前在線賬號信息存入本側(cè)的動態(tài)集合,程序以客戶端側(cè)的該集合為遍歷源,通過列表渲染在面板中刷新所有在線用戶信息,并按列表結(jié)構(gòu)展示。在此期間,服務(wù)端發(fā)出廣播將新上線賬號的信息推送給其他在線用戶,通知每個在線的賬號都刷新好友列表。
(4)未讀消息提示。
當(dāng)前賬號上線后,程序檢查本地的未讀消息,在遍歷每條消息時都會根據(jù)消息發(fā)言人對應(yīng)的ID去匹配當(dāng)前賬號的在線好友列表,若當(dāng)前賬號在線好友存在未讀消息對應(yīng)發(fā)言人,則在好友列表上增加渲染該賬號未讀消息的數(shù)量[6]。
(5)未讀消息清空。
當(dāng)用戶打開當(dāng)前賬號與其他賬號的對話窗口時,瀏覽器客戶端將通知服務(wù)端檢測這2個賬號的歷史對話記錄中是否存在當(dāng)前賬號未讀消息。對于存在的未讀消息,當(dāng)對話窗口打開后,程序?qū)⒛J(rèn)當(dāng)前賬號已經(jīng)閱讀了和對端賬號的所有歷史未讀消息,此時會同步清零該窗口的未讀消息數(shù)量標(biāo)記。
目前,基于WebSocket協(xié)議設(shè)計的全雙工教學(xué)答疑系統(tǒng)已經(jīng)完成了核心功能的構(gòu)建,這部分功能正在小范圍層面內(nèi)開展灰度測試。客戶端以尺寸相對開闊的電腦側(cè)瀏覽器為主,頁面整體布局設(shè)計相對容易。移動端的整體適配也將逐步納入后期計劃。根據(jù)局域網(wǎng)目前試用效果反饋,依托于案例資源庫為載體的教學(xué)答疑系統(tǒng)增加即時通信功能后,學(xué)生普遍反映該功能的實用性較高,即時互動性提升了他們參與集體討論的熱情和學(xué)習(xí)案例的參與感,增加了學(xué)生對該系統(tǒng)的黏性。這項功能設(shè)計對案例教學(xué)的效率和效果都有比較明顯的正向促進(jìn)作用。即時通信功能只是WebSocket協(xié)議的一種應(yīng)用形式,其他與之關(guān)系密切的應(yīng)用方向還包括協(xié)作編輯等,這些應(yīng)用形態(tài)可以促進(jìn)課程資源整體生態(tài)不斷完善和豐富。這項技術(shù)方向的研究將根據(jù)教學(xué)改革的指引方向進(jìn)行調(diào)整,待現(xiàn)有功能驗證成熟后,可考慮擴展該工具與其他教學(xué)資源間的雙向聯(lián)通,不斷強化服務(wù)教學(xué)業(yè)務(wù)場景的教輔軟件研究導(dǎo)向,更好地輔助“三全育人”理念落到實處。