本節(jié)主要翻譯一下websocket的協(xié)議。其中,socket通信開發(fā),最重要的就是協(xié)議了。通信軟件(QQ、MSN)、殺毒軟件(360、金山)、電信軟件(短信、通話)等行業(yè)軟件有自己的協(xié)議。有了協(xié)議,我們可以無視語言和平臺(tái),使得大家都可以為這個(gè)平臺(tái)做開發(fā),就像我們用了同一種語言,同一個(gè)電波一樣??偟膩碚f,在通信程序開發(fā)中,協(xié)議成為了分步式處理、跨平臺(tái)、跨語言的重要作用,在websocket中也不例外。
協(xié)議分很多種,OSI的七層協(xié)議,如果現(xiàn)在記得不清楚的也沒關(guān)系。在開發(fā)中,我們幾乎只需了解TCP協(xié)議就行了,這里由于篇幅原因,也不對(duì)整編websocket協(xié)議進(jìn)行整篇翻譯。只對(duì)其中的幾點(diǎn)需注意的地方進(jìn)行一個(gè)說明吧。
注1:This Internet-Draft will expire on November 7, 2010.
P2 本篇過期時(shí)間為到2010年11月7日。這個(gè)應(yīng)該不準(zhǔn),這個(gè)要瀏覽器的支持了,像Filefox4.0才會(huì)完全支持html5,如果你使用Chrome,那么也跟你得到的版本有關(guān)。不是那么特別的。
注2:A simpler solution would be to use a single TCP connection for traffic in both directions
websocket是一種基于一個(gè)TCP連接的全雙工的通訊方式,也就是說,服務(wù)端可以主動(dòng)推數(shù)據(jù)到客戶端,客戶端也可以發(fā)送數(shù)據(jù)到服務(wù)端。
注3:1.2. Protocol overview
The handshake from the client looks as follows:[省去協(xié)議內(nèi)容]
The handshake from the server looks as follows:[省去協(xié)議內(nèi)容]
在webcoket中,是由客戶端先發(fā)送請(qǐng)求頭信息到服務(wù)端,服務(wù)端對(duì)請(qǐng)求進(jìn)行檢查,如果是合法的請(qǐng)求頭,則會(huì)發(fā)送握手信息到客戶端。同是為每個(gè)客戶端建產(chǎn)一個(gè)socket用來通信。這個(gè)socket有輸入流,也有輸出流,是一個(gè)全雙工的tcp通信端口。
其中客戶端的請(qǐng)求頭和服務(wù)端的握手信息都是每行一個(gè)的鍵值對(duì)信息,且字符編碼為ASCII 編碼。這個(gè)很重要,因?yàn)樵趥魉蛿?shù)據(jù)的時(shí)候,是以utf8做編碼的。
注4:1.3 Opening handshake
建產(chǎn)握手。這個(gè)是整個(gè)websocket協(xié)議中最重要的一個(gè)環(huán)節(jié)。因?yàn)槲帐质墙⑦B接,或進(jìn)行下一步通信的關(guān)鍵,也是關(guān)系到你是否能和其它遵尋html5 websocket協(xié)議的瀏覽器(如chrome,fiirfox4.0等)進(jìn)行通信的關(guān)鍵。
下面主要講一點(diǎn)比較不容易計(jì)算的的地方。
Sec-WebSocket-Key1: 18x 6]8vM;54 *(5: { U1]8 z [ 8
Sec-WebSocket-Key2: 1_ tx7X d < nw 334J702) 7]o}` 0
For each of these fields, the server has to take the digits from the
value to obtain a number (in this case 1868545188 and 1733470270
respectively), then divide that number by the number of spaces
characters in the value (in this case 12 and 10) to obtain a 32-bit
number (155712099 and 173347027). These two resulting numbers are
then used in the server handshake, as described below.
這里的兩個(gè)key值,分別代表兩個(gè)數(shù)。把上面的兩個(gè)字符數(shù)數(shù)組轉(zhuǎn)化成字符串后,變成了1868545188和1733470270。然后,再查看這兩個(gè)key中空格字符的個(gè)數(shù)。
第一個(gè)key一共有12個(gè)空格。所以1868545188/12=155712099.同理,第二個(gè)key一共有10個(gè)空格1733470270/10=173347027
注5:P6 Data is sent in the form of UTF-8 text. Each frame of data starts with a 0x00 byte and ends with a 0xFF byte, with the UTF-8 text in between….
當(dāng)握手成功后,就是進(jìn)行數(shù)據(jù)傳送了。注意 ,這個(gè)時(shí)候tcp連接已在經(jīng)建立了,現(xiàn)在客戶發(fā)送上來的時(shí)候就是純純的數(shù)據(jù)了。服務(wù)端要判斷什么時(shí)候是一次數(shù)據(jù)請(qǐng)求的開始,什么時(shí)候是請(qǐng)求的結(jié)束。這個(gè)也要是處理在tcp發(fā)送中的黏包的問題。由于在tcp協(xié)議中,會(huì)存在兩個(gè)緩沖區(qū)去存放發(fā)送的數(shù)據(jù)或接收的數(shù)據(jù),如果沒有顯的分割符則會(huì)讓服務(wù)端無法正確的識(shí)別兩條命令。
在websocket中,由于瀏覽端和服務(wù)端已經(jīng)打好招呼,我發(fā)送的內(nèi)容為utf-8 編碼,如果我發(fā)送0x00,表是是一條命令的開始,如果發(fā)磅了0xFF,就表示這條命令已經(jīng)結(jié)束了。這樣就可以在瀏覽器的配合下很好解決上面黏包的問題。
也可由下圖所示:
Handshake
|
V
Frame type byte <--------------------------------------.
| | |
| `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
| |
`--> (0x80 to 0xFE) --> Length --> Data... ------->-'
注6: P8 The |Origin| field is used to protect against unauthorized cross-
origin use of a WebSocket server by scripts using the |WebSocket| API
in a Web browser. The server specifies which origin it is willing to
receive requests from by including a |Sec-WebSocket-Origin| field
with that origin. If multiple origins are authorized, the server
echoes the value in the |Origin| field of the client's handshake.
請(qǐng)求中的Origin字段,可以用來做身份驗(yàn)證的作用,如果使用得當(dāng),可以減少非法來源的連接建產(chǎn)。可以結(jié)合SEC-websocket-Origin來使用。其次,在請(qǐng)求中,還會(huì)伴隨傳過來頭信息的md5碼,可以起到防篡改的作用,可以進(jìn)一步增強(qiáng)安全性驗(yàn)證。其實(shí),還有一招,就算連接已經(jīng)建立,我們還可以通過讓客戶端請(qǐng)求用戶名和密碼的方式使用業(yè)務(wù)邏輯再經(jīng)過一次驗(yàn)證。
注7:P10 1.4 Cloing handshake
每個(gè)端只要向另一端口發(fā)送一個(gè)0xFF的信息,就表示連接已結(jié)束了。這個(gè)相關(guān)于tcp/ip協(xié)議中的fin/ack.
注8: 1.5 Design philosophy
這節(jié)是非正式的,但是作者有提到,websocket是可以和http共用監(jiān)聽端口的,以后也可能會(huì)擴(kuò)展協(xié)議,由于現(xiàn)在傳送的是字符串,后期可能會(huì)追求更好的壓縮率,采用二進(jìn)制傳送。
其實(shí),我們用現(xiàn)的協(xié)議開發(fā)時(shí),也可以在發(fā)送的時(shí)候把數(shù)據(jù)壓縮,在接收的時(shí)候把數(shù)據(jù)解壓縮。
注9:3.1 Parsing websoket URLS
If the /secure/ flag is false, then append the string "ws://" to
/url/. Otherwise, append the string "wss://" to /url/.
處理websocket鏈接。服務(wù)端只會(huì)去識(shí)別ws://或wss://開頭的請(qǐng)求,這樣的話,就不會(huì)和其它的監(jiān)聽服務(wù)進(jìn)行沖突出了吧。
注:客戶端發(fā)送的請(qǐng)求中,服務(wù)端地址為wss://www.example.com:8787/im?id=123456
那么www.example.com是服務(wù)端的地址,監(jiān)聽的端口號(hào)為8787,im是對(duì)應(yīng)的請(qǐng)求名稱,其中傳送的參數(shù)為id,值為123456.
注10 :4 Client-side requirements
這章主要是以客戶端(瀏覽器)為中心。所以一切的主語都是客戶端。詳細(xì)講了客戶端發(fā)送請(qǐng)求頭和數(shù)據(jù)信息的內(nèi)容。
注11 :5 Server-Side requirements
這章主要是以服務(wù)端(監(jiān)聽服務(wù))為中心,詳細(xì)服務(wù)端如何處理請(qǐng)求和處理握手的過程。
引用:原文鏈接:http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
聯(lián)系客服