咱们知道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