WebSocket自定义协议

WebSocket协议的优势之一是能在其基础上建立广泛的应用层协议。
在建立WebSocket连接时可以在请求头中加入Sec-WebSocket-Protocol首标,服务器选择0个或者1个协议,响应一个带有和客户端请求相同的协议名称的Sec-WebSocket-Protocol首标。
在WebSocket基础上自定义协议类型进行数据解析,对于明确数据形式有很大的帮助。

Nodejs简单实现:

客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WebSocket 自定义协议测试</title>
</head>
<body>

<script>
let wsUrl = 'ws://localhost:8080';
let ws = new WebSocket(wsUrl, ['xxx', 'yyy', 'zzz']);
ws.onopen = () => {
console.log(ws.protocol);
ws.send('testProtocol: ');
}
ws.onmessage = (message) => {
console.log(message.data);
}
</script>

</body>
</html>
服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
'use strict'
const WebSocket = require('ws');

const handleProtocolsMessage = {
'xxx': (message, ws) => {
ws.send(message + 'xxx');
},
'yyy': (message, ws) => {
ws.send(message + 'yyy');
},
'zzz': (message, ws) => {
ws.send(message + 'zzz');
}
};

const websocket = new WebSocket.Server({
port: 8080,
verifyClient: (info, done) => {
done(true);
},
handleProtocols: (protocols, req) => {
// 协议选择
return protocols[Number.parseInt(Math.random()*protocols.length)];
}
});

websocket.on('connection', (ws, req) => {
ws.on('message', message => {
// 根据不同的自定义协议,选择不同的数据解析方式
handleProtocolsMessage[ws.protocol](message, ws);
});
ws.on('close', closeCode => {
console.log(closeCode);
});
});
示例图