咱們知道websocket一種服務端推送技術,首先Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。後續數據傳遞是基於TCP的。javascript
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>websocket client</title> </head> <body> <button id="open">open</button> <button id="send">send</button> <button id="close">close</button> <script type="text/javascript"> (function (){ let ws = null; document.querySelector("#open").addEventListener('click', e => { ws = new WebSocket("ws://127.0.0.1:8080"); ws.addEventListener('open', e => console.log('open event, %o', e)); ws.addEventListener('message', e => console.log('message event, %o', e)); ws.addEventListener('close', e => console.log('close event, %o', e)); ws.addEventListener('error', e => console.log('error event, %o', e)); }); document.querySelector("#send").addEventListener('click', e => { ws.send('hello'); }); document.querySelector("#close").addEventListener('click', e => { ws.close(); ws = null; }); })() </script> </body> </html>
const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('received: %s', message); ws.send('hello too!'); }); ws.send('something'); });
open event, Event message event, MessageEvent message event, MessageEvent close event, CloseEvent
從瀏覽器中能夠看到ws握手的請求頭信息html
GET ws://127.0.0.1:8080/ HTTP/1.1 Host: 127.0.0.1:8080 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Origin: http://zj.h5.m.taobao.com Sec-WebSocket-Version: 13 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.8 Cookie: OUTFOX_SEARCH_USER_ID_NCOO=1973383732.1783078; l=AujoRgw9fUEEs1APUgk9dNwgONz6EUwb Sec-WebSocket-Key: 7iAt/aVzQLvkwZmO6eHr3A== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
解釋:java
Upgrade: websocket Connection: Upgrade
表示發起的是Websocket協議。web
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: 32BWzg94jPj8C0kXzqHAru5pGbw=
101 code 轉換協議:101 Switching Protocols
服務器已經理解了客戶端的請求,並將經過Upgrade 消息頭通知客戶端採用不一樣的協議來完成這個請求。在發送完這個響應最後的空行後,服務器將會切換到在Upgrade 消息頭中定義的那些協議。
只有在切換新的協議更有好處的時候才應該採起相似措施。例如,切換到新的HTTP 版本比舊版本更有優點,或者切換到一個實時且同步的協議以傳送利用此類特性的資源。shell
之上是應用層協議的內容,用wireshark抓包看下底層細節,先梳理下TCP協議自己。瀏覽器
這是握手時HTTP協議底層依賴的TCP三次握手機制:最後一個是告訴客戶端沒有內容發送了。8080 爲服務端端口號,61476 端口爲客戶端端口號。服務器
從HTTP 協議轉爲 websocket 協議,5001 端口號爲 websocket 服務的端口號。websocket
能夠看出61475端口一開始爲HTTP服務的,後來因爲101返回碼,61475 端口轉爲 websocket 的 5001 端口號,服務端的8080端口對接客戶端的5001端口號。關閉websocket時,由 61475 端口號發起關閉 5001 請求,與此同時 61475 端口和 服務端的8080端口通訊,告訴服務端我要關閉端口,成功後61475 再告訴 5001 端口,我關閉成功了。整個關閉流程結束。socket