alemonjs 2.1.0-alpha.25 → 2.1.0-alpha.26

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/cbp/config.js CHANGED
@@ -12,7 +12,9 @@ const USER_AGENT_HEADER = 'user-agent';
12
12
  //
13
13
  const USER_AGENT_HEADER_VALUE_MAP = {
14
14
  platform: 'platform',
15
- client: 'client'};
15
+ client: 'client',
16
+ testone: 'testone'
17
+ };
16
18
  // 设备 ID
17
19
  const DEVICE_ID_HEADER = 'x-device-id';
18
20
  // 是否全量接收
package/lib/cbp/index.js CHANGED
@@ -3,371 +3,432 @@ import { WebSocketServer, WebSocket } from 'ws';
3
3
  import router from './router.js';
4
4
  import koaCors from '@koa/cors';
5
5
  import { ResultCode } from '../core/code.js';
6
- import { USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, platformClient, fullClient, childrenClient, childrenBind } from './config.js';
6
+ import { platformClient, childrenClient, fullClient, childrenBind, USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER } from './config.js';
7
7
  import { getConfig } from '../core/config.js';
8
8
  import * as flattedJSON from 'flatted';
9
9
  import { connectionTestOne } from './testone.js';
10
10
 
11
+ function getReConnectTime() {
12
+ const time = 1000 * 1;
13
+ const curTime = time;
14
+ const mTime = (curTime / 1000 / 60).toFixed(2);
15
+ logger.info({
16
+ code: ResultCode.Fail,
17
+ message: `[ws-discord] 等待 ${mTime} 分钟后重新连接`,
18
+ data: null
19
+ });
20
+ return curTime;
21
+ }
11
22
  const cbpServer = (port, listeningListener) => {
12
23
  if (global.chatbotServer) {
13
24
  delete global.chatbotServer;
14
25
  }
15
- // create
16
- const app = new Koa();
17
- // MessageRouter
18
- app.use(router.routes());
19
- app.use(router.allowedMethods());
20
- // Cors
21
- app.use(koaCors({
22
- origin: '*', // 允许所有来源
23
- allowMethods: ['GET', 'POST', 'PUT', 'DELETE'] // 允许的 HTTP 方法
24
- }));
25
- const server = app.listen(port, listeningListener);
26
- // 创建 WebSocketServer 并监听同一个端口
27
- global.chatbotServer = new WebSocketServer({ server });
28
- /**
29
- *
30
- * @param originId
31
- * @param ws
32
- */
33
- const setPlatformClient = (originId, ws) => {
34
- // 仅允许有一个平台连接
35
- if (platformClient.size > 0) {
36
- logger.error({
37
- code: ResultCode.Fail,
38
- message: `平台连接已存在: ${originId}`,
39
- data: null
40
- });
41
- ws.close(); // 关闭新连接
42
- return;
43
- }
44
- // 设置平台客户端
45
- platformClient.set(originId, ws);
46
- // 处理api
47
- const handleApi = (DeviceId, message) => {
48
- // 指定的设备 处理消费。终端有记录每个客户端是谁
49
- if (childrenClient.has(DeviceId)) {
50
- const clientWs = childrenClient.get(DeviceId);
51
- if (clientWs && clientWs.readyState === WebSocket.OPEN) {
52
- // 发送消息到指定的子客户端
53
- clientWs.send(message);
54
- }
55
- else {
56
- // 如果连接已关闭,删除该客户端
57
- childrenClient.delete(DeviceId);
58
- }
59
- }
60
- else if (fullClient.has(DeviceId)) {
61
- const clientWs = fullClient.get(DeviceId);
62
- if (clientWs && clientWs.readyState === WebSocket.OPEN) {
63
- // 发送消息到指定的全量客户端
64
- clientWs.send(message);
65
- }
66
- else {
67
- // 如果连接已关闭,删除该客户端
68
- fullClient.delete(DeviceId);
69
- }
70
- }
71
- };
72
- // 处理 action
73
- const handleAction = (DeviceId, message) => {
74
- if (childrenClient.has(DeviceId)) {
75
- const clientWs = childrenClient.get(DeviceId);
76
- if (clientWs && clientWs.readyState === WebSocket.OPEN) {
77
- // 发送消息到指定的子客户端
78
- clientWs.send(message);
79
- }
80
- else {
81
- // 如果连接已关闭,删除该客户端
82
- childrenClient.delete(DeviceId);
83
- }
84
- }
85
- else if (fullClient.has(DeviceId)) {
86
- const clientWs = fullClient.get(DeviceId);
87
- if (clientWs && clientWs.readyState === WebSocket.OPEN) {
88
- // 发送消息到指定的全量客户端
89
- clientWs.send(message);
90
- }
91
- else {
92
- // 如果连接已关闭,删除该客户端
93
- fullClient.delete(DeviceId);
94
- }
95
- }
96
- };
97
- // 处理事件
98
- const handleEvent = (message, ID) => {
99
- // 全量客户端
100
- fullClient.forEach((clientWs, clientId) => {
101
- // 检查状态 并检查状态
102
- if (clientWs.readyState === WebSocket.OPEN) {
103
- clientWs.send(message);
104
- }
105
- else {
106
- // 如果连接已关闭,删除该客户端
107
- childrenClient.delete(clientId);
108
- }
109
- });
110
- // 根据所在群进行分流。
111
- // 确保同一个频道的消息。都流向同一个客户端。
112
- if (!ID) {
113
- logger.error({
114
- code: ResultCode.Fail,
115
- message: '消息缺少标识符 ID',
116
- data: null
117
- });
118
- return;
119
- }
120
- // 重新绑定并发送消息
121
- const reBind = () => {
122
- if (childrenClient.size === 0) {
123
- return;
124
- }
125
- else if (childrenClient.size === 1) {
126
- // 只有一个客户端,直接绑定
127
- const [bindId, clientWs] = childrenClient.entries().next().value;
128
- childrenBind.set(ID, bindId);
129
- clientWs.send(message);
26
+ const createServer = () => {
27
+ try {
28
+ // create
29
+ const app = new Koa();
30
+ // MessageRouter
31
+ app.use(router.routes());
32
+ app.use(router.allowedMethods());
33
+ // Cors
34
+ app.use(koaCors({
35
+ origin: '*', // 允许所有来源
36
+ allowMethods: ['GET', 'POST', 'PUT', 'DELETE'] // 允许的 HTTP 方法
37
+ }));
38
+ const server = app.listen(port, listeningListener);
39
+ // 创建 WebSocketServer 并监听同一个端口
40
+ global.chatbotServer = new WebSocketServer({ server });
41
+ /**
42
+ *
43
+ * @param originId
44
+ * @param ws
45
+ */
46
+ const setPlatformClient = (originId, ws) => {
47
+ // 仅允许有一个平台连接
48
+ if (platformClient.size > 0) {
49
+ logger.error({
50
+ code: ResultCode.Fail,
51
+ message: `平台连接已存在: ${originId}`,
52
+ data: null
53
+ });
54
+ ws.close(); // 关闭新连接
130
55
  return;
131
56
  }
132
- // 有多个客户端,找到绑定最少的那个。
133
- // 如果大家都一样。就拿最近的第一个直接绑定。
134
- let minBindCount = Infinity;
135
- let bindId = null;
136
- childrenClient.forEach((_, id) => {
137
- const count = Array.from(childrenBind.values()).filter(v => v === id).length;
138
- if (count < minBindCount) {
139
- minBindCount = count;
140
- bindId = id;
57
+ // 设置平台客户端
58
+ platformClient.set(originId, ws);
59
+ // 处理api
60
+ const handleApi = (DeviceId, message) => {
61
+ // 指定的设备 处理消费。终端有记录每个客户端是谁
62
+ if (childrenClient.has(DeviceId)) {
63
+ const clientWs = childrenClient.get(DeviceId);
64
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
65
+ // 发送消息到指定的子客户端
66
+ clientWs.send(message);
67
+ }
68
+ else {
69
+ // 如果连接已关闭,删除该客户端
70
+ childrenClient.delete(DeviceId);
71
+ }
141
72
  }
142
- });
143
- if (bindId) {
144
- const clientWs = childrenClient.get(bindId);
145
- if (clientWs && clientWs.readyState === WebSocket.OPEN) {
73
+ else if (fullClient.has(DeviceId)) {
74
+ const clientWs = fullClient.get(DeviceId);
75
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
76
+ // 发送消息到指定的全量客户端
77
+ clientWs.send(message);
78
+ }
79
+ else {
80
+ // 如果连接已关闭,删除该客户端
81
+ fullClient.delete(DeviceId);
82
+ }
83
+ }
84
+ };
85
+ // 处理 action
86
+ const handleAction = (DeviceId, message) => {
87
+ if (childrenClient.has(DeviceId)) {
88
+ const clientWs = childrenClient.get(DeviceId);
89
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
90
+ // 发送消息到指定的子客户端
91
+ clientWs.send(message);
92
+ }
93
+ else {
94
+ // 如果连接已关闭,删除该客户端
95
+ childrenClient.delete(DeviceId);
96
+ }
97
+ }
98
+ else if (fullClient.has(DeviceId)) {
99
+ const clientWs = fullClient.get(DeviceId);
100
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
101
+ // 发送消息到指定的全量客户端
102
+ clientWs.send(message);
103
+ }
104
+ else {
105
+ // 如果连接已关闭,删除该客户端
106
+ fullClient.delete(DeviceId);
107
+ }
108
+ }
109
+ };
110
+ // 处理事件
111
+ const handleEvent = (message, ID) => {
112
+ // 全量客户端
113
+ fullClient.forEach((clientWs, clientId) => {
114
+ // 检查状态 并检查状态
115
+ if (clientWs.readyState === WebSocket.OPEN) {
116
+ clientWs.send(message);
117
+ }
118
+ else {
119
+ // 如果连接已关闭,删除该客户端
120
+ childrenClient.delete(clientId);
121
+ }
122
+ });
123
+ // 根据所在群进行分流。
124
+ // 确保同一个频道的消息。都流向同一个客户端。
125
+ if (!ID) {
126
+ logger.error({
127
+ code: ResultCode.Fail,
128
+ message: '消息缺少标识符 ID',
129
+ data: null
130
+ });
131
+ return;
132
+ }
133
+ // 重新绑定并发送消息
134
+ const reBind = () => {
135
+ if (childrenClient.size === 0) {
136
+ return;
137
+ }
138
+ else if (childrenClient.size === 1) {
139
+ // 只有一个客户端,直接绑定
140
+ const [bindId, clientWs] = childrenClient.entries().next().value;
141
+ childrenBind.set(ID, bindId);
142
+ clientWs.send(message);
143
+ return;
144
+ }
145
+ // 有多个客户端,找到绑定最少的那个。
146
+ // 如果大家都一样。就拿最近的第一个直接绑定。
147
+ let minBindCount = Infinity;
148
+ let bindId = null;
149
+ childrenClient.forEach((_, id) => {
150
+ const count = Array.from(childrenBind.values()).filter(v => v === id).length;
151
+ if (count < minBindCount) {
152
+ minBindCount = count;
153
+ bindId = id;
154
+ }
155
+ });
156
+ if (bindId) {
157
+ const clientWs = childrenClient.get(bindId);
158
+ if (clientWs && clientWs.readyState === WebSocket.OPEN) {
159
+ // 进行绑定
160
+ childrenBind.set(ID, bindId);
161
+ // 发送消息到绑定的客户端
162
+ clientWs.send(message);
163
+ }
164
+ else {
165
+ // 如果连接已关闭,删除该客户端
166
+ childrenClient.delete(bindId);
167
+ // 重新进行绑定
168
+ reBind();
169
+ }
170
+ }
171
+ else {
172
+ logger.error({
173
+ code: ResultCode.Fail,
174
+ message: '服务端出现意外,无法绑定客户端',
175
+ data: null
176
+ });
177
+ }
178
+ };
179
+ // 判断该id是否被分配过
180
+ if (!childrenBind.has(ID)) {
146
181
  // 进行绑定
147
- childrenBind.set(ID, bindId);
148
- // 发送消息到绑定的客户端
149
- clientWs.send(message);
182
+ reBind();
183
+ return;
150
184
  }
151
- else {
185
+ const bindId = childrenBind.get(ID);
186
+ if (!childrenClient.has(bindId)) {
187
+ // 出现意外。
188
+ // 重新进行绑定。
189
+ reBind();
190
+ return;
191
+ }
192
+ const clientWs = childrenClient.get(bindId);
193
+ if (!clientWs || clientWs.readyState !== WebSocket.OPEN) {
152
194
  // 如果连接已关闭,删除该客户端
153
195
  childrenClient.delete(bindId);
154
196
  // 重新进行绑定
155
197
  reBind();
198
+ return;
156
199
  }
157
- }
158
- else {
200
+ clientWs.send(message);
201
+ };
202
+ // 得到平台客户端的消息
203
+ ws.on('message', (message) => {
204
+ try {
205
+ // 解析消息
206
+ const parsedMessage = flattedJSON.parse(message.toString());
207
+ // 1. 解析得到 actionId ,说明是消费行为请求。要广播告诉所有客户端。
208
+ // 2. 解析得到 name ,说明是一个事件请求。
209
+ // 3. 解析得到 apiId ,说明是一个接口请求。
210
+ // 4. 解析得到 testID ,说明是一个测试请求。
211
+ logger.debug({
212
+ code: ResultCode.Ok,
213
+ message: '服务端接收到消息',
214
+ data: parsedMessage
215
+ });
216
+ if (parsedMessage.apiId) {
217
+ // 指定的设备 处理消费。终端有记录每个客户端是谁
218
+ const DeviceId = parsedMessage.DeviceId;
219
+ handleApi(DeviceId, message);
220
+ }
221
+ else if (parsedMessage?.actionId) {
222
+ // 指定的设备 处理消费。终端有记录每个客户端是谁
223
+ const DeviceId = parsedMessage.DeviceId;
224
+ handleAction(DeviceId, message);
225
+ }
226
+ else if (parsedMessage?.name) {
227
+ const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
228
+ handleEvent(message, ID);
229
+ }
230
+ else if (parsedMessage?.testID) {
231
+ // 继续解析数据。测试请求。
232
+ }
233
+ }
234
+ catch (error) {
235
+ logger.error({
236
+ code: ResultCode.Fail,
237
+ message: '服务端解析平台消息失败',
238
+ data: error
239
+ });
240
+ return;
241
+ }
242
+ });
243
+ // 处理关闭事件
244
+ ws.on('close', () => {
245
+ platformClient.delete(originId);
246
+ logger.debug({
247
+ code: ResultCode.Fail,
248
+ message: `Client ${originId} disconnected`,
249
+ data: null
250
+ });
251
+ });
252
+ ws.on('error', err => {
159
253
  logger.error({
160
254
  code: ResultCode.Fail,
161
- message: '服务端出现意外,无法绑定客户端',
255
+ message: `Client ${originId} error`,
256
+ data: err
257
+ });
258
+ });
259
+ };
260
+ // 设置子客户端
261
+ const setChildrenClient = (originId, ws) => {
262
+ childrenClient.set(originId, ws);
263
+ // 得到子客户端的消息。只会是actions请求。
264
+ ws.on('message', (message) => {
265
+ // tudo
266
+ // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
267
+ // 导致无法进行多个平台连接。
268
+ if (platformClient.size > 0) {
269
+ platformClient.forEach((platformWs, platformId) => {
270
+ // 检查平台客户端状态
271
+ if (platformWs.readyState === WebSocket.OPEN) {
272
+ platformWs.send(message);
273
+ }
274
+ else {
275
+ // 如果连接已关闭,删除该平台客户端
276
+ platformClient.delete(platformId);
277
+ }
278
+ });
279
+ }
280
+ });
281
+ // 处理关闭事件
282
+ ws.on('close', () => {
283
+ childrenClient.delete(originId);
284
+ logger.debug({
285
+ code: ResultCode.Fail,
286
+ message: `Client ${originId} disconnected`,
162
287
  data: null
163
288
  });
164
- }
289
+ });
290
+ ws.on('error', err => {
291
+ logger.error({
292
+ code: ResultCode.Fail,
293
+ message: `Client ${originId} error`,
294
+ data: err
295
+ });
296
+ });
297
+ };
298
+ // 全量客户端
299
+ const setFullClient = (originId, ws) => {
300
+ fullClient.set(originId, ws);
301
+ // 处理消息事件
302
+ ws.on('message', (message) => {
303
+ // tudo
304
+ // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
305
+ // 导致无法进行多个平台连接。
306
+ if (platformClient.size > 0) {
307
+ platformClient.forEach((platformWs, platformId) => {
308
+ // 检查平台客户端状态
309
+ if (platformWs.readyState === WebSocket.OPEN) {
310
+ platformWs.send(message);
311
+ }
312
+ else {
313
+ // 如果连接已关闭,删除该平台客户端
314
+ platformClient.delete(platformId);
315
+ }
316
+ });
317
+ }
318
+ });
319
+ // 处理关闭事件
320
+ ws.on('close', () => {
321
+ fullClient.delete(originId);
322
+ logger.debug({
323
+ code: ResultCode.Fail,
324
+ message: `Client ${originId} disconnected`,
325
+ data: null
326
+ });
327
+ });
165
328
  };
166
- // 判断该id是否被分配过
167
- if (!childrenBind.has(ID)) {
168
- // 进行绑定
169
- reBind();
170
- return;
171
- }
172
- const bindId = childrenBind.get(ID);
173
- if (!childrenClient.has(bindId)) {
174
- // 出现意外。
175
- // 重新进行绑定。
176
- reBind();
177
- return;
178
- }
179
- const clientWs = childrenClient.get(bindId);
180
- if (!clientWs || clientWs.readyState !== WebSocket.OPEN) {
181
- // 如果连接已关闭,删除该客户端
182
- childrenClient.delete(bindId);
183
- // 重新进行绑定
184
- reBind();
185
- return;
186
- }
187
- clientWs.send(message);
188
- };
189
- // 得到平台客户端的消息
190
- ws.on('message', (message) => {
191
- try {
192
- // 解析消息
193
- const parsedMessage = flattedJSON.parse(message.toString());
194
- // 1. 解析得到 actionId ,说明是消费行为请求。要广播告诉所有客户端。
195
- // 2. 解析得到 name ,说明是一个事件请求。
196
- // 3. 解析得到 apiId ,说明是一个接口请求。
197
- // 4. 解析得到 testID ,说明是一个测试请求。
329
+ // 处理客户端连接
330
+ global.chatbotServer.on('connection', (ws, request) => {
331
+ // 测试平台的连接
332
+ if (request.url === '/testone') {
333
+ connectionTestOne(ws, request);
334
+ return;
335
+ }
336
+ // 读取请求头中的 来源
337
+ const headers = request.headers;
338
+ const origin = headers[USER_AGENT_HEADER] || USER_AGENT_HEADER_VALUE_MAP.client;
339
+ // 来源id
340
+ const originId = headers[DEVICE_ID_HEADER];
341
+ if (!originId) {
342
+ // 如果没有来源 ID,拒绝连接
343
+ ws.close(4000, 'Missing Device ID');
344
+ return;
345
+ }
198
346
  logger.debug({
199
347
  code: ResultCode.Ok,
200
- message: '服务端接收到消息',
201
- data: parsedMessage
348
+ message: `Client ${originId} connected`,
349
+ data: null
202
350
  });
203
- if (parsedMessage.apiId) {
204
- // 指定的设备 处理消费。终端有记录每个客户端是谁
205
- const DeviceId = parsedMessage.DeviceId;
206
- handleApi(DeviceId, message);
207
- }
208
- else if (parsedMessage?.actionId) {
209
- // 指定的设备 处理消费。终端有记录每个客户端是谁
210
- const DeviceId = parsedMessage.DeviceId;
211
- handleAction(DeviceId, message);
351
+ // 根据来源进行分类
352
+ if (origin === USER_AGENT_HEADER_VALUE_MAP.platform) {
353
+ setPlatformClient(originId, ws);
354
+ return;
212
355
  }
213
- else if (parsedMessage?.name) {
214
- const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
215
- handleEvent(message, ID);
356
+ else if (origin === USER_AGENT_HEADER_VALUE_MAP.client) {
357
+ // 连接时,需要给客户端发送主动消息
358
+ ws.send(flattedJSON.stringify({
359
+ active: 'sync',
360
+ payload: {
361
+ value: getConfig().value,
362
+ args: getConfig().argv,
363
+ package: {
364
+ version: getConfig().package?.version
365
+ },
366
+ env: {
367
+ login: process.env.login,
368
+ platform: process.env.platform,
369
+ port: process.env.port
370
+ }
371
+ },
372
+ // 主动消息
373
+ activeId: originId
374
+ }));
216
375
  }
217
- else if (parsedMessage?.testID) {
218
- // 继续解析数据。测试请求。
376
+ const isFullReceive = headers[FULL_RECEIVE_HEADER] === '1';
377
+ // 如果是全量接收
378
+ if (isFullReceive) {
379
+ setFullClient(originId, ws);
380
+ return;
219
381
  }
220
- }
221
- catch (error) {
222
- logger.error({
223
- code: ResultCode.Fail,
224
- message: '服务端解析平台消息失败',
225
- data: error
226
- });
227
- return;
228
- }
229
- });
230
- // 处理关闭事件
231
- ws.on('close', () => {
232
- delete platformClient[originId];
233
- logger.debug({
234
- code: ResultCode.Fail,
235
- message: `Client ${originId} disconnected`,
236
- data: null
382
+ setChildrenClient(originId, ws);
237
383
  });
238
- });
239
- ws.on('error', err => {
240
- logger.error({
241
- code: ResultCode.Fail,
242
- message: `Client ${originId} error`,
243
- data: err
384
+ chatbotServer.on('error', (err) => {
385
+ // 清理所有客户端连接
386
+ platformClient.clear();
387
+ childrenClient.clear();
388
+ fullClient.clear();
389
+ // 发现是端口已经被占用
390
+ if (err.code === 'EADDRINUSE') {
391
+ logger.error({
392
+ code: ResultCode.FailInternal,
393
+ message: `端口 ${port} 已被占用,请检查是否有其他服务在运行`,
394
+ data: err.message
395
+ });
396
+ const reCreateTime = getReConnectTime();
397
+ // 清理所有客户端连接,开始重新创建服务器
398
+ setTimeout(() => {
399
+ createServer();
400
+ }, reCreateTime);
401
+ }
402
+ else {
403
+ logger.error({
404
+ code: ResultCode.FailInternal,
405
+ message: 'WebSocket server error',
406
+ data: err.message || 'Unknown error'
407
+ });
408
+ }
244
409
  });
245
- });
246
- };
247
- // 设置子客户端
248
- const setChildrenClient = (originId, ws) => {
249
- childrenClient.set(originId, ws);
250
- // 得到子客户端的消息。只会是actions请求。
251
- ws.on('message', (message) => {
252
- // tudo
253
- // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
254
- // 导致无法进行多个平台连接。
255
- if (platformClient.size > 0) {
256
- platformClient.forEach(platformWs => {
257
- // 检查平台客户端状态
258
- if (platformWs.readyState === WebSocket.OPEN) {
259
- platformWs.send(message);
260
- }
261
- else {
262
- // 如果连接已关闭,删除该平台客户端
263
- platformClient.delete(originId);
264
- }
410
+ chatbotServer.on('close', () => {
411
+ logger.info({
412
+ code: ResultCode.Ok,
413
+ message: 'WebSocket server closed',
414
+ data: null
265
415
  });
266
- }
267
- });
268
- // 处理关闭事件
269
- ws.on('close', () => {
270
- delete childrenClient[originId];
271
- logger.debug({
272
- code: ResultCode.Fail,
273
- message: `Client ${originId} disconnected`,
274
- data: null
416
+ // 清理所有客户端连接
417
+ platformClient.clear();
418
+ childrenClient.clear();
419
+ fullClient.clear();
275
420
  });
276
- });
277
- ws.on('error', err => {
421
+ }
422
+ catch (error) {
278
423
  logger.error({
279
- code: ResultCode.Fail,
280
- message: `Client ${originId} error`,
281
- data: err
282
- });
283
- });
284
- };
285
- // 全量客户端
286
- const setFullClient = (originId, ws) => {
287
- fullClient.set(originId, ws);
288
- // 处理消息事件
289
- ws.on('message', (message) => {
290
- // tudo
291
- // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
292
- // 导致无法进行多个平台连接。
293
- if (platformClient.size > 0) {
294
- platformClient.forEach(platformWs => {
295
- // 检查平台客户端状态
296
- if (platformWs.readyState === WebSocket.OPEN) {
297
- platformWs.send(message);
298
- }
299
- else {
300
- // 如果连接已关闭,删除该平台客户端
301
- platformClient.delete(originId);
302
- }
303
- });
304
- }
305
- });
306
- // 处理关闭事件
307
- ws.on('close', () => {
308
- delete fullClient[originId];
309
- logger.debug({
310
- code: ResultCode.Fail,
311
- message: `Client ${originId} disconnected`,
312
- data: null
424
+ code: ResultCode.FailInternal,
425
+ message: '创建 CBP 服务器失败',
426
+ data: error
313
427
  });
314
- });
315
- };
316
- // 处理客户端连接
317
- global.chatbotServer.on('connection', (ws, request) => {
318
- // 测试平台的连接
319
- if (request.url === '/testone') {
320
- connectionTestOne(ws);
321
- return;
322
- }
323
- // 读取请求头中的 来源
324
- const headers = request.headers;
325
- const origin = headers[USER_AGENT_HEADER] || USER_AGENT_HEADER_VALUE_MAP.client;
326
- // 来源id
327
- const originId = headers[DEVICE_ID_HEADER];
328
- if (!originId) {
329
- // 如果没有来源 ID,拒绝连接
330
- ws.close(4000, 'Missing Device ID');
331
- return;
332
- }
333
- logger.debug({
334
- code: ResultCode.Ok,
335
- message: `Client ${originId} connected`,
336
- data: null
337
- });
338
- // 根据来源进行分类
339
- if (origin === USER_AGENT_HEADER_VALUE_MAP.platform) {
340
- setPlatformClient(originId, ws);
341
428
  return;
342
429
  }
343
- else if (origin === USER_AGENT_HEADER_VALUE_MAP.client) {
344
- // 连接时,需要给客户端发送主动消息
345
- ws.send(flattedJSON.stringify({
346
- active: 'sync',
347
- payload: {
348
- value: getConfig().value,
349
- args: getConfig().argv,
350
- package: {
351
- version: getConfig().package?.version
352
- },
353
- env: {
354
- login: process.env.login,
355
- platform: process.env.platform,
356
- port: process.env.port
357
- }
358
- },
359
- // 主动消息
360
- activeId: originId
361
- }));
362
- }
363
- const isFullReceive = headers[FULL_RECEIVE_HEADER] === '1';
364
- // 如果是全量接收
365
- if (isFullReceive) {
366
- setFullClient(originId, ws);
367
- return;
368
- }
369
- setChildrenClient(originId, ws);
370
- });
430
+ };
431
+ createServer();
371
432
  };
372
433
 
373
434
  export { cbpServer };
package/lib/cbp/router.js CHANGED
@@ -3,11 +3,12 @@ import KoaRouter from 'koa-router';
3
3
  const router = new KoaRouter({
4
4
  prefix: '/'
5
5
  });
6
- // 测试服务是否存在
7
- router.get('/cbp', ctx => {
6
+ // 响应服务在线
7
+ router.get('/online', ctx => {
8
+ ctx.status = 200;
8
9
  ctx.body = {
9
10
  code: 200,
10
- message: 'Message API is working',
11
+ message: 'service online',
11
12
  data: null
12
13
  };
13
14
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alemonjs",
3
- "version": "2.1.0-alpha.25",
3
+ "version": "2.1.0-alpha.26",
4
4
  "description": "bot script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",