alemonjs 2.1.0-alpha.4 → 2.1.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app/load.js +9 -13
- package/lib/cbp/config.js +4 -2
- package/lib/cbp/connect.js +118 -5
- package/package.json +1 -1
package/lib/app/load.js
CHANGED
|
@@ -51,7 +51,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
51
51
|
// 卸载
|
|
52
52
|
App.un();
|
|
53
53
|
try {
|
|
54
|
-
await app
|
|
54
|
+
app?.unMounted && (await app.unMounted(e));
|
|
55
55
|
}
|
|
56
56
|
catch (e) {
|
|
57
57
|
// 卸载周期出意外,不需要进行卸载
|
|
@@ -59,15 +59,13 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
// onCreated 创建
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
62
|
+
try {
|
|
63
|
+
app?.onCreated && (await app?.onCreated());
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
unMounted(e);
|
|
67
|
+
// 出错了,结束后续的操作。
|
|
68
|
+
return;
|
|
71
69
|
}
|
|
72
70
|
// onMounted 加载
|
|
73
71
|
try {
|
|
@@ -119,9 +117,7 @@ const loadChildren = async (mainPath, appName) => {
|
|
|
119
117
|
App.pushMiddleware(mwData);
|
|
120
118
|
App.on();
|
|
121
119
|
try {
|
|
122
|
-
|
|
123
|
-
await app?.onMounted({ response: resData, middleware: mwData });
|
|
124
|
-
}
|
|
120
|
+
app?.onMounted && (await app.onMounted({ response: resData, middleware: mwData }));
|
|
125
121
|
}
|
|
126
122
|
catch (e) {
|
|
127
123
|
unMounted(e);
|
package/lib/cbp/config.js
CHANGED
|
@@ -26,6 +26,8 @@ const generateUniqueId = () => {
|
|
|
26
26
|
// 超时时间
|
|
27
27
|
const timeoutTime = 1000 * 12; // 12秒
|
|
28
28
|
// 失败重连
|
|
29
|
-
const reconnectInterval =
|
|
29
|
+
const reconnectInterval = 1000 * 6; // 6秒
|
|
30
|
+
// 心跳间隔
|
|
31
|
+
const HEARTBEAT_INTERVAL = 1000 * 18; // 18秒
|
|
30
32
|
|
|
31
|
-
export { DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, USER_AGENT_HEADER, actionResolves, actionTimeouts, childrenBind, childrenClient, deviceId, fullClient, generateUniqueId, platformClient, reconnectInterval, timeoutTime };
|
|
33
|
+
export { DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, HEARTBEAT_INTERVAL, USER_AGENT_HEADER, actionResolves, actionTimeouts, childrenBind, childrenClient, deviceId, fullClient, generateUniqueId, platformClient, reconnectInterval, timeoutTime };
|
package/lib/cbp/connect.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WebSocket } from 'ws';
|
|
2
2
|
import { onProcessor } from '../app/event-processor.js';
|
|
3
3
|
import { ResultCode } from '../core/code.js';
|
|
4
|
-
import { deviceId, FULL_RECEIVE_HEADER, DEVICE_ID_HEADER, USER_AGENT_HEADER, actionResolves, actionTimeouts, reconnectInterval } from './config.js';
|
|
4
|
+
import { deviceId, FULL_RECEIVE_HEADER, DEVICE_ID_HEADER, USER_AGENT_HEADER, actionResolves, actionTimeouts, reconnectInterval, HEARTBEAT_INTERVAL } from './config.js';
|
|
5
5
|
import '../app/define-chidren.js';
|
|
6
6
|
import '../app/event-middleware.js';
|
|
7
7
|
import '../app/event-response.js';
|
|
@@ -17,6 +17,63 @@ import '../app/message-api.js';
|
|
|
17
17
|
import '../app/message-format.js';
|
|
18
18
|
import { createResult } from '../app/utils.js';
|
|
19
19
|
|
|
20
|
+
// 心跳
|
|
21
|
+
const useHeartbeat = ({ ping, isConnected, terminate, }) => {
|
|
22
|
+
let heartbeatTimer = null;
|
|
23
|
+
let lastPong = Date.now();
|
|
24
|
+
const stopHeartbeat = () => {
|
|
25
|
+
if (heartbeatTimer) {
|
|
26
|
+
clearInterval(heartbeatTimer);
|
|
27
|
+
heartbeatTimer = null;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const callback = () => {
|
|
31
|
+
if (isConnected()) {
|
|
32
|
+
const diff = Date.now() - lastPong;
|
|
33
|
+
const max = HEARTBEAT_INTERVAL * 2; // 最大心跳间隔
|
|
34
|
+
// 检查上次 pong 是否超时
|
|
35
|
+
if (diff > max) {
|
|
36
|
+
logger.debug({
|
|
37
|
+
code: ResultCode.Fail,
|
|
38
|
+
message: '心跳超时,断开重连',
|
|
39
|
+
data: null
|
|
40
|
+
});
|
|
41
|
+
terminate(); // 强制断开
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
ping();
|
|
45
|
+
logger.debug({
|
|
46
|
+
code: ResultCode.Ok,
|
|
47
|
+
message: `发送 ping`,
|
|
48
|
+
data: null
|
|
49
|
+
});
|
|
50
|
+
heartbeatTimer = setTimeout(callback, HEARTBEAT_INTERVAL);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
stopHeartbeat(); // 如果连接已关闭,停止心跳
|
|
54
|
+
terminate(); // 强制断开
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const startHeartbeat = () => {
|
|
58
|
+
lastPong = Date.now();
|
|
59
|
+
stopHeartbeat();
|
|
60
|
+
callback();
|
|
61
|
+
};
|
|
62
|
+
const control = {
|
|
63
|
+
start: startHeartbeat,
|
|
64
|
+
stop: stopHeartbeat,
|
|
65
|
+
pong: () => {
|
|
66
|
+
// 收到 pong,说明连接正常
|
|
67
|
+
lastPong = Date.now();
|
|
68
|
+
logger.debug({
|
|
69
|
+
code: ResultCode.Ok,
|
|
70
|
+
message: `收到 pong`,
|
|
71
|
+
data: null
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return [control];
|
|
76
|
+
};
|
|
20
77
|
/**
|
|
21
78
|
* CBP 客户端
|
|
22
79
|
* @param url
|
|
@@ -31,6 +88,27 @@ const cbpClient = (url, options = {}) => {
|
|
|
31
88
|
delete global.chatbotClient;
|
|
32
89
|
}
|
|
33
90
|
const { open = () => { }, isFullReceive = true } = options;
|
|
91
|
+
const [heartbeatControl] = useHeartbeat({
|
|
92
|
+
ping: () => {
|
|
93
|
+
global.chatbotClient.ping?.();
|
|
94
|
+
},
|
|
95
|
+
isConnected: () => {
|
|
96
|
+
return global.chatbotClient && global.chatbotClient.readyState === WebSocket.OPEN;
|
|
97
|
+
},
|
|
98
|
+
terminate: () => {
|
|
99
|
+
try {
|
|
100
|
+
// 强制断开连接
|
|
101
|
+
global.chatbotClient.terminate?.();
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
logger.debug({
|
|
105
|
+
code: ResultCode.Fail,
|
|
106
|
+
message: '强制断开连接失败',
|
|
107
|
+
data: error
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
34
112
|
const start = () => {
|
|
35
113
|
global.chatbotClient = new WebSocket(url, {
|
|
36
114
|
headers: {
|
|
@@ -39,7 +117,13 @@ const cbpClient = (url, options = {}) => {
|
|
|
39
117
|
[FULL_RECEIVE_HEADER]: isFullReceive ? '1' : '0'
|
|
40
118
|
}
|
|
41
119
|
});
|
|
42
|
-
global.chatbotClient.on('open',
|
|
120
|
+
global.chatbotClient.on('open', () => {
|
|
121
|
+
open();
|
|
122
|
+
heartbeatControl.start(); // 启动心跳
|
|
123
|
+
});
|
|
124
|
+
global.chatbotClient.on('pong', () => {
|
|
125
|
+
heartbeatControl.pong(); // 更新 pong 时间
|
|
126
|
+
});
|
|
43
127
|
// 客户端接收,被标准化的平台消息
|
|
44
128
|
global.chatbotClient.on('message', message => {
|
|
45
129
|
try {
|
|
@@ -96,7 +180,8 @@ const cbpClient = (url, options = {}) => {
|
|
|
96
180
|
}
|
|
97
181
|
});
|
|
98
182
|
global.chatbotClient.on('close', () => {
|
|
99
|
-
|
|
183
|
+
heartbeatControl.stop(); // 停止心跳
|
|
184
|
+
logger.warn({
|
|
100
185
|
code: ResultCode.Fail,
|
|
101
186
|
message: '连接关闭,尝试重新连接...',
|
|
102
187
|
data: null
|
|
@@ -124,6 +209,27 @@ const cbpPlatform = (url, options = {
|
|
|
124
209
|
delete global.chatbotPlatform;
|
|
125
210
|
}
|
|
126
211
|
const { open = () => { } } = options;
|
|
212
|
+
const [heartbeatControl] = useHeartbeat({
|
|
213
|
+
ping: () => {
|
|
214
|
+
global.chatbotClient.ping?.();
|
|
215
|
+
},
|
|
216
|
+
isConnected: () => {
|
|
217
|
+
return global.chatbotClient && global.chatbotClient.readyState === WebSocket.OPEN;
|
|
218
|
+
},
|
|
219
|
+
terminate: () => {
|
|
220
|
+
try {
|
|
221
|
+
// 强制断开连接
|
|
222
|
+
global.chatbotClient.terminate?.();
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
logger.debug({
|
|
226
|
+
code: ResultCode.Fail,
|
|
227
|
+
message: '强制断开连接失败',
|
|
228
|
+
data: error
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
127
233
|
/**
|
|
128
234
|
* 发送数据
|
|
129
235
|
* @param data
|
|
@@ -168,7 +274,13 @@ const cbpPlatform = (url, options = {
|
|
|
168
274
|
[DEVICE_ID_HEADER]: deviceId
|
|
169
275
|
}
|
|
170
276
|
});
|
|
171
|
-
global.chatbotPlatform.on('open',
|
|
277
|
+
global.chatbotPlatform.on('open', () => {
|
|
278
|
+
open();
|
|
279
|
+
heartbeatControl.start(); // 启动心跳
|
|
280
|
+
});
|
|
281
|
+
global.chatbotPlatform.on('pong', () => {
|
|
282
|
+
heartbeatControl.pong(); // 更新 pong 时间
|
|
283
|
+
});
|
|
172
284
|
global.chatbotPlatform.on('message', message => {
|
|
173
285
|
try {
|
|
174
286
|
const data = JSON.parse(message.toString());
|
|
@@ -192,7 +304,8 @@ const cbpPlatform = (url, options = {
|
|
|
192
304
|
}
|
|
193
305
|
});
|
|
194
306
|
global.chatbotPlatform.on('close', err => {
|
|
195
|
-
|
|
307
|
+
heartbeatControl.stop(); // 停止心跳
|
|
308
|
+
logger.warn({
|
|
196
309
|
code: ResultCode.Fail,
|
|
197
310
|
message: '平台端连接关闭,尝试重新连接...',
|
|
198
311
|
data: err
|