WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,任何一方都可以主动发消息给对方。比如说,服务器可以在任意时刻发送消息给浏览器
WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接
WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
GET ws://localhost:3000/ws/chat HTTP/1.1 Host: localhost Upgrade: websocket Connection: Upgrade Origin: http://localhost:3000 Sec-WebSocket-Key: client-random-string Sec-WebSocket-Version: 13
- GET请求的地址不是类似
/path/
,而是以ws://
开头的地址;- 请求头
Upgrade: websocket
和Connection: Upgrade
表示这个连接将要被转换为WebSocket连接;Sec-WebSocket-Key
是用于标识这个连接,并非用于加密数据;Sec-WebSocket-Version
指定了WebSocket的协议版本。
服务器如果接受该请求,就会返回如下响应:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: server-random-string
该响应代码
101
表示本次连接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket
指定的WebSocket协议。
一个WebSocket连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。
ws
模块既包含了服务器端,又包含了客户端。
在Node.js中,使用最广泛的WebSocket模块是ws
,我们创建一个hello-ws
的VS Code工程,然后在package.json
中添加ws
的依赖:
{ "name": "hello-ws", "version": "0.0.1", "dependencies": { "ws": "1.1.1" } }
// 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = WebSocket.Server; // 实例化: const wss = new WebSocketServer({ port: 3000 });
如果有WebSocket请求接入,wss
对象可以响应connection
事件来处理这个WebSocket:
wss.on('connection', function (ws) { console.log(`[SERVER] connection()`); ws.on('message', function (message) { console.log(`[SERVER] Received: ${message}`); ws.send(`ECHO: ${message}`, (err) => { if (err) { console.log(`[SERVER] error: ${err}`); } }); }) });
// 打开一个WebSocket: var ws = new WebSocket('ws://localhost:3000/test'); // 响应onmessage事件: ws.onmessage = function(msg) { console.log(msg); }; // 给服务器发送一个字符串: ws.send('Hello!');