WebSocket是一种在单个TCP连接上进行全双工通信的网络协议,它使得客户端和服务器之间的数据交换变得更加简单高效。WebSocket协议在2011年被IETF定为标准RFC 6455,由W3C标准化,现在所有现代浏览器都已经支持。
在传统的HTTP协议中,通信只能由客户端发起,服务器被动响应。如果服务器有连续的状态变化,客户端要获知就非常麻烦,只能使用"轮询"的方式,每隔一段时间就发一个请求去询问服务器有没有新信息。轮询的效率低,非常浪费资源,因为需要不断建立HTTP连接。
WebSocket协议的出现解决了这个问题,它允许服务器主动向客户端推送信息,客户端也可以主动向服务器发送信息,实现了真正的双向平等对话。
WebSocket建立连接后,客户端和服务器可以同时向对方发送数据,实现真正的双向通信。
WebSocket的底层是TCP协议,和HTTP协议同属应用层,但WebSocket是独立的协议,只是在握手阶段借用了HTTP协议。
WebSocket默认端口也是80和443,并且握手阶段采用HTTP协议,因此不容易被防火墙拦截,能通过各种HTTP代理服务器。
WebSocket协议的头部信息很小,相比HTTP每次请求都要携带完整的头部,WebSocket的通信开销要小得多。
WebSocket不仅可以发送文本数据,还可以直接发送二进制数据(Blob或ArrayBuffer)。
WebSocket协议没有同源限制,客户端可以与任意服务器通信,当然服务器端可以做相应的安全限制。
WebSocket的连接建立需要经过一个"握手"的过程,这个过程是通过HTTP协议完成的:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
| 特性 | HTTP长轮询 | WebSocket |
|---|---|---|
| 通信方向 | 半双工(客户端主动拉取) | 全双工(双向实时通信) |
| 延迟 | 较高(需要等待请求周期) | 极低(实时推送) |
| 开销 | 大(每次请求都有HTTP头部) | 小(连接建立后头部极小) |
| 连接数 | 频繁建立和断开 | 一次建立,持续连接 |
| 服务器压力 | 大(大量并发请求) | 小(长连接维护) |
| 适用场景 | 低频率更新 | 高频率实时通信 |
WebSocket最经典的应用就是在线聊天,消息可以实时推送到对方,不需要刷新页面。
多人在线游戏需要实时同步游戏状态,WebSocket的低延迟特性非常适合。
股票行情、体育比分、监控数据等需要实时更新的场景,都可以用WebSocket来推送数据。
多人同时编辑文档时,需要实时同步每个人的编辑操作,WebSocket可以实现这一点。
网站的消息通知、系统公告等,可以通过WebSocket实时推送给用户。
物联网设备的状态上报和控制指令下发,也可以使用WebSocket来实现。
// 创建WebSocket连接
const ws = new WebSocket('ws://example.com/socket');
// 连接打开时触发
ws.onopen = function() {
console.log('WebSocket连接已建立');
// 发送消息
ws.send('Hello, WebSocket!');
};
// 收到消息时触发
ws.onmessage = function(event) {
console.log('收到消息:', event.data);
};
// 连接关闭时触发
ws.onclose = function() {
console.log('WebSocket连接已关闭');
};
// 连接出错时触发
ws.onerror = function(error) {
console.error('WebSocket错误:', error);
};
const WebSocket = require('ws');
// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });
// 监听连接事件
wss.on('connection', function connection(ws) {
console.log('新的客户端连接');
// 收到消息时
ws.on('message', function incoming(message) {
console.log('收到消息:', message);
// 向客户端发送消息
ws.send('服务器收到了你的消息:' + message);
});
// 连接关闭时
ws.on('close', function() {
console.log('客户端断开连接');
});
});
WebSocket握手阶段是HTTP请求,可以利用HTTP的Cookie、Token等方式进行身份验证。
和HTTP一样,WebSocket也有对应的加密版本WSS(WebSocket Secure),使用TLS/SSL加密,对应HTTPS的443端口。
服务器端应该验证请求的Origin头,防止恶意网站建立WebSocket连接。
应该对单条消息的大小做限制,防止恶意发送超大消息导致服务器内存溢出。
WebSocket是一项非常重要的网络技术,它彻底改变了Web应用的通信模式,让实时交互变得简单高效。从即时聊天到在线游戏,从数据监控到协同办公,WebSocket都发挥着重要的作用。
随着Web应用的发展,对实时性的要求越来越高,WebSocket也变得越来越重要。掌握WebSocket技术,是现代Web开发者必备的技能之一。