在有些情况下,我们在使用 WebSocket
通信的时候,需要对方进行回应,但由于 WebSocket
是全双工
交互,所以不能像 http
协议一样,发送之后能够得到对应的回复,为了能够很好的获取到对应的回复,设计了一个简单的协议,各位有需要的话,可以参考看看。
协议的原理很简单,即:记录消息ID
。
举个例子🌰
JavaScript 发送数据需要对方进行回复;那么对发送的数据进行封装:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 sendJson = function (json) {
return new Promise(((resolve, reject) => {
let dataPackage = {
_message_id: json.$_message_id || {web_id: 0, sdk_id: 0},
data: json,
}
dataPackage._message_id.web_id = _message_id++;
if (_message_id > _callback_max_id) {
_message_id = 0;
}
try {
webSocket.send(JSON.stringify(dataPackage));
_callback[dataPackage._message_id.web_id] = {
resolve: resolve, reject: reject
}
} catch (e) {
reject(e);
}
}));
}
webSocket.onmessage = async function (event) {
try {
let dataPackage = JSON.parse(event.data);
let _message_id = dataPackage._message_id;
let json = dataPackage.data;
json.$_message_id = _message_id;
let message;
try {
if (_message_id && _message_id.web_id > 0) {
let func = _callback[_message_id.web_id];
delete _callback[_message_id.web_id];
_message_id.web_id = 0;
json.$_message_id.web_id = 0;
if (json.code >= 0) {
func.resolve(json);
} else {
func.reject(json);
}
} else {
message = option && option.onmessage && await option.onmessage(json);
}
} catch (e) {
message = {
code: -1,
message: typeof e == "string" ? e : JSON.stringify(e),
data: null,
};
} finally {
let dataPackage = {
_message_id: _message_id,
data: message
}
delete message.$_message_id;
if (dataPackage._message_id && dataPackage._message_id.sdk_id) {
self.sendJsonBack(dataPackage);
}
}
} catch (e) {
}
};变量说明:
web_id
和sdk_id
在这里分别表示网页端消息 id 和sdk
(我这边另一头是作为sdk
提供,所以命名为sdk_id
) 端消息ID。webSocket
为WebSocket
对象,用于接收和发送WebSocket
数据。_callback
与_callback_max_id
分别为记录回调函数
,以及最大回调记录
,可以在接收到回复的情况下进行回调,从而与发送关联。onmessage
为WebSocket
接收数据回调,通过接收的_message_id
内web_id
和sdk_id
(JavaScript
端主要是web_id
),然后根据webSocket
进行对应数据回调。- 为保证对方也能够得到消息的回复,所以在
finally
也进行dataPackage._message_id.sdk_id
即sdk_id
的判定,如果对方发送的数据包含dataPackage._message_id.sdk_id
,那么表示这个包为发送包,非回应包,需要JavaScript
这端进行回应。
JavaScript
端完整例子:
1 | const _callback_max_id = 1000000000; |