錢鑫博
摘要:瀏覽器里的Web應用和計算機的串口硬件進行通信時,需要針對不同的瀏覽器開發不同的插件。采用HTML5內置的WebSocket技術和QT開發框架,通過WebSocket協議連接本地服務,并通過本地服務綁定串口完成全雙工通信的方案,實現了跨瀏覽器的Web應用與客戶端計算機串口通信的技術,解決了為不同瀏覽器產品及版本開發多種插件的問題。經過測試驗證,達到了預期目標。
關鍵詞:WebSocket;HTML5技術;串口通信
中圖分類號:TP393文獻標志碼:A文章編號:1008-1739(2020)14-62-4

0引言
隨著互聯網的不斷發展,軟件趨向于網絡化,很多計算機上的應用都做成了B/S架構,客戶端打開瀏覽器就可以進行訪問。但是出于安全考慮,瀏覽器與操作系統進行了隔離,瀏覽器不允許Web應用直接訪問客戶端的硬件,訪問硬件就只能開發插件。每種瀏覽器各自的API不兼容,Chrome瀏覽器用NPAPI來執行一個本地程序獲取硬件,Firefox瀏覽器使用JS-Ctypes技術實現插件,然后調用C++代碼等來獲取本地硬件。瀏覽器迭代速度快、接口變化大,開發插件時常遇到瀏覽器更新導致不能用,客戶體驗非常差,而且每次都開發對應版本的插件費時費力。WebSocket是HTML5規范中的一個部分,借鑒了Socket思想,為了Web應用程序和服務端全雙工通信而專門制定的一種新的應用層協議。
1 WebSocket協議及幀結構
WebSocket Protocol是HTML5中一種新的協議,實現了瀏覽器與服務器全雙工通信(full-duplex)。在這之前都是客戶端主動請求服務端,請求一次應答一次,很多時候實現消息更新都是采用Ajax輪詢,有延遲。有了WebSocket,雙方都可以主動發給對端,實現真正的推送。WebSocket連接創建后,客戶端和服務端進行數據交換時,協議控制的數據包頭部較小。在不包含頭部的情況下,服務端到客戶端的包頭只有2~10 Byte(取決于數據包長度),客戶端到服務端需要加上額外的4 Byte掩碼。而HTTP協議每次通信都需要攜帶完整的頭部[1]。RFC文檔給出的WebSocket協議格式,如圖1所示。

WebSocket協議報文是分幀傳輸,FIN:1 bit,代表是否是尾幀,如果為1,即為最后片段;RSV1,RSV2,RSV3:每個占1 bit,為擴展保留的,若建立連接時使用了擴展,那么這些位的含義應自定義好;opcode:4 bit,定義負載數據(payload data)的類型,如表1所示。

WebSocket有控制幀和數據幀2種,opcode最高位為1的都是控制幀,opcode最高位為0的都是數據幀。應用級的數據傳輸幀,有文本幀和二進制幀2種。協議級別的控制報文幀,有關閉幀、ping幀和pong幀3種。關閉幀:opcode 0x8,連接任一端想關閉WebSocket,就發一個關閉幀給對端,對端收到該幀,若之前沒有發過關閉幀,則必須回復一個關閉幀。ping幀和pong幀:用來心跳檢測和判斷對端是否還連接,連接建立后任一端都可以發送ping幀,收到ping的一端必須回復pong幀。
masked:1 bit,表示是否進行掩碼處理,客戶端發送給服務端時為1,服務端發送給客戶端時為0。根據WebSocket的定義,客戶端發送數據需要進行掩碼處理,接收數據無需反掩碼操作,服務端發送數據無需進行掩碼處理,接收數據需要反掩碼操作。
payload length:7 bit,如果第2個字節的后面7 bit的十進制值≤125,則直接用7 bit表示數據長度;如果該值為126,表示數據長度是126~65 535,這時要用3~4 Byte,每個字節8 bit,即16 bit來表示數據長度;如果該值為127,則說明數據長度已經>65 535,16 bit也已經不足以表示數據長度了,這時就用3~10 Byte,即64 bit來表示數據長度。
masking key:當masked為1的時候才存在,用于對需要的數據進行解密。
payload data:負載數據,就是要傳輸的數據。如果masked為1,該數據會被加密,要通過與masking key的值進行異或運算解密才能獲取真正的負載數據。負載數據=擴展數據+應用數據。擴展數據包含在總負載數據長度中,其實就是自定義一個協議,如果有擴展數據,擴展數據就加在應用數據前面,并且要協商好擴展數據長度如何計算。應用數據是指擴展數據之后幀的剩余部分。
2方案設計
2.1本地服務的結構
本地服務主要實現WebSocket的服務端的串口控制和數據轉發。WebSocket服務端用來處理客戶端的瀏覽器Web應用連接,串口控制用來操作計算機的串口設備,本地服務內部轉接雙方的數據實現數據轉發傳輸[2],本地服務結構如圖2所示。
