wechaty-puppet-matrix 0.0.24 → 0.0.27

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.
@@ -1,7 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import { log } from '@juzi/wechaty-puppet';
3
3
  import { EventEmitter } from 'events';
4
- import WebSocket from 'ws';
5
4
  import * as PUPPET from '@juzi/wechaty-puppet';
6
5
  import { format, getUnixTime } from 'date-fns';
7
6
  import { xmlToJson } from '../utils/xml-to-json.js';
@@ -305,17 +304,13 @@ const genImageSnsXml = (wxid, contentDesc, mediaList, location) => {
305
304
  class Client extends EventEmitter {
306
305
  options;
307
306
  connectionStatus = { status: 'disconnected' };
308
- MAX_RECONNECT_ATTEMPTS = 10;
309
- INITIAL_RECONNECT_DELAY = 1000;
310
- MAX_RECONNECT_DELAY = 30000;
311
- HEARTBEAT_INTERVAL = 40 * 1000;
312
- HEARTBEAT_TIMEOUT = 5000;
313
- reconnectAttempts = 0;
314
307
  heartbeatTimer;
308
+ checkExpiredInterval;
315
309
  heartbeatTimeoutTimer;
316
310
  getQrcodeTimes = 0;
317
311
  restoreTimes = 0;
318
312
  maxRestoreTimes = 1;
313
+ hasExpired = false;
319
314
  socket;
320
315
  server;
321
316
  tokenInfo;
@@ -337,12 +332,35 @@ class Client extends EventEmitter {
337
332
  this.getQrcodeTimes = 0;
338
333
  this.restoreTimes = 0;
339
334
  this.maxRestoreTimes = 1;
335
+ this.hasExpired = false;
336
+ }
337
+ destroy() {
338
+ log.verbose(PRE, 'destroy()');
339
+ this.hasEmitLogout = false;
340
+ this.socket && this.socket.end();
341
+ this.socket = null;
342
+ this.checkExpiredInterval && clearInterval(this.checkExpiredInterval);
343
+ this.checkExpiredInterval = undefined;
344
+ this.heartbeatTimer && clearTimeout(this.heartbeatTimer);
345
+ this.heartbeatTimer = undefined;
346
+ this.heartbeatTimeoutTimer && clearTimeout(this.heartbeatTimeoutTimer);
347
+ this.heartbeatTimeoutTimer = undefined;
340
348
  }
341
349
  async getTokenInfo() {
342
350
  try {
343
351
  const res = await axios.get(`https://api-bot.aibotk.com/openapi/v1/token/info?secret=5be06b6f8d42a7&token=${this.options.token}`);
344
352
  if (res.data.code === 0) {
345
353
  this.tokenInfo = res.data.data;
354
+ this.hasExpired = res.data?.data?.hasExpired;
355
+ if (this.hasExpired) {
356
+ log.error('Token已到期,请及时续费');
357
+ this.checkExpiredInterval && clearInterval(this.checkExpiredInterval);
358
+ this.checkExpiredInterval = undefined;
359
+ setTimeout(() => {
360
+ this.emit('expired', true);
361
+ }, 3000);
362
+ return false;
363
+ }
346
364
  return true;
347
365
  }
348
366
  else {
@@ -355,8 +373,15 @@ class Client extends EventEmitter {
355
373
  return false;
356
374
  }
357
375
  }
376
+ checkHasExpired() {
377
+ this.checkExpiredInterval = setInterval(() => {
378
+ log.info('checkHasExpired');
379
+ void this.getTokenInfo();
380
+ }, 1000 * 60 * 60 * 12);
381
+ }
358
382
  async initServer() {
359
383
  await this.getTokenInfo();
384
+ this.checkHasExpired();
360
385
  if (this.socket) {
361
386
  log.error('socket had already been opened!');
362
387
  return;
@@ -364,6 +389,9 @@ class Client extends EventEmitter {
364
389
  await this.createMqttConnection();
365
390
  }
366
391
  async createMqttConnection() {
392
+ if (this.hasExpired) {
393
+ return;
394
+ }
367
395
  if (!this.tokenInfo) {
368
396
  log.error('Token info not available');
369
397
  return;
@@ -381,7 +409,6 @@ class Client extends EventEmitter {
381
409
  });
382
410
  client.on('connect', () => {
383
411
  this.connectionStatus.status = 'connected';
384
- this.reconnectAttempts = 0;
385
412
  log.info('MQTT connection opened');
386
413
  this.socket = client;
387
414
  client.subscribe(`aibotk/msg/${this.tokenInfo.guid}`, (err) => {
@@ -399,11 +426,12 @@ class Client extends EventEmitter {
399
426
  client.on('close', () => {
400
427
  this.connectionStatus.status = 'disconnected';
401
428
  log.warn('MQTT connection closed');
402
- this.socket = null;
403
- void this.reconnect();
429
+ });
430
+ client.on('reconnect', () => {
431
+ this.connectionStatus.status = 'reconnecting';
432
+ log.warn('MQTT connection Reconnecting...');
404
433
  });
405
434
  client.on('message', (topic, message) => {
406
- this.resetHeartbeatTimeout();
407
435
  log.verbose(PRE, 'Received message on topic %s: %s', topic, message.toString());
408
436
  if (message.toString() === 'ping' || message.toString() === 'pong') {
409
437
  log.verbose('Received heartbeat');
@@ -420,159 +448,6 @@ class Client extends EventEmitter {
420
448
  }
421
449
  });
422
450
  this.socket = client;
423
- this.startHeartbeat();
424
- }
425
- async createWebSocket() {
426
- if (!this.tokenInfo) {
427
- log.error('Token info not available');
428
- return;
429
- }
430
- const ws = new WebSocket(`${this.tokenInfo.endpoint}?guid=${this.tokenInfo.guid}`, {
431
- perMessageDeflate: true,
432
- maxPayload: 100 * 1024 * 1024,
433
- });
434
- await new Promise((resolve, reject) => {
435
- ws.once('open', () => {
436
- this.connectionStatus.status = 'connected';
437
- this.reconnectAttempts = 0;
438
- log.info('WebSocket connection opened');
439
- resolve();
440
- });
441
- ws.once('error', (error) => {
442
- log.warn('WebSocket connection error', error);
443
- reject(error);
444
- });
445
- ws.once('close', (code, reason) => {
446
- void this.handleWebSocketClose(code, reason);
447
- reject(new Error(`WebSocket closed: ${code} - ${reason}`));
448
- });
449
- });
450
- this.socket = ws;
451
- this.setupWebSocketListeners(ws);
452
- }
453
- setupWebSocketListeners(ws) {
454
- ws.on('message', (data) => {
455
- this.resetHeartbeatTimeout();
456
- log.silly(PRE, 'initWebSocket() ws.on(message): %s', data);
457
- if (data.toString() === 'pong') {
458
- log.verbose('Received heartbeat');
459
- return;
460
- }
461
- try {
462
- const payload = JSON.parse(data);
463
- log.info('Received payload', JSON.stringify(payload));
464
- void this.eventParse(payload);
465
- }
466
- catch (error) {
467
- log.warn(PRE, 'initWebSocket() ws.on(message) exception: %s', error);
468
- this.emit('error', error.message);
469
- }
470
- });
471
- ws.on('error', (error) => {
472
- if (error.code === 'ECONNREFUSED') {
473
- log.verbose('Connection refused, potential reconnect scenario');
474
- return;
475
- }
476
- log.verbose(PRE, 'initWebSocket() ws.on(error) %s', error);
477
- this.emit('error', error);
478
- });
479
- ws.on('close', (code, reason) => {
480
- this.stopHeartbeat();
481
- void this.handleWebSocketClose(code, reason);
482
- });
483
- this.startHeartbeat();
484
- }
485
- startHeartbeat() {
486
- this.stopHeartbeat();
487
- this.heartbeatTimer = setInterval(() => {
488
- if (this.socket?.connected) {
489
- try {
490
- this.socket.publish(`aibotk/msg/${this.tokenInfo.guid}`, 'pong');
491
- this.setHeartbeatTimeout();
492
- }
493
- catch (error) {
494
- log.error('Failed to send heartbeat:', error);
495
- void this.handleMqttClose();
496
- }
497
- }
498
- }, this.HEARTBEAT_INTERVAL);
499
- }
500
- stopHeartbeat() {
501
- if (this.heartbeatTimer) {
502
- clearInterval(this.heartbeatTimer);
503
- this.heartbeatTimer = undefined;
504
- }
505
- if (this.heartbeatTimeoutTimer) {
506
- clearTimeout(this.heartbeatTimeoutTimer);
507
- this.heartbeatTimeoutTimer = undefined;
508
- }
509
- }
510
- setHeartbeatTimeout() {
511
- if (this.heartbeatTimeoutTimer) {
512
- clearTimeout(this.heartbeatTimeoutTimer);
513
- }
514
- this.heartbeatTimeoutTimer = setTimeout(() => {
515
- log.warn('Heartbeat timeout, reconnecting...');
516
- void this.handleMqttClose();
517
- }, this.HEARTBEAT_TIMEOUT);
518
- }
519
- resetHeartbeatTimeout() {
520
- if (this.heartbeatTimeoutTimer) {
521
- clearTimeout(this.heartbeatTimeoutTimer);
522
- this.heartbeatTimeoutTimer = undefined;
523
- }
524
- }
525
- async handleMqttClose() {
526
- this.connectionStatus.status = 'disconnected';
527
- log.warn('MQTT connection closed');
528
- if (this.socket) {
529
- this.socket.end();
530
- this.socket = null;
531
- }
532
- await this.reconnectMqtt();
533
- }
534
- async reconnectMqtt() {
535
- if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
536
- log.error('Max reconnect attempts reached. Stopping reconnection.');
537
- return;
538
- }
539
- const delay = Math.min(this.INITIAL_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts), this.MAX_RECONNECT_DELAY);
540
- this.reconnectAttempts++;
541
- log.info(`Reconnecting in ${delay}ms (Attempt ${this.reconnectAttempts})`);
542
- setTimeout(() => {
543
- try {
544
- void this.createMqttConnection();
545
- }
546
- catch (error) {
547
- log.warn('Reconnection failed', error);
548
- }
549
- }, delay);
550
- }
551
- async handleWebSocketClose(code, reason) {
552
- this.connectionStatus.status = 'disconnected';
553
- log.warn(`WebSocket closed: Code ${code}, Reason ${reason}`);
554
- if (this.socket) {
555
- this.socket.close();
556
- this.socket = null;
557
- }
558
- await this.reconnect();
559
- }
560
- async reconnect() {
561
- if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
562
- log.error('Max reconnect attempts reached. Stopping reconnection.');
563
- return;
564
- }
565
- const delay = Math.min(this.INITIAL_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts), this.MAX_RECONNECT_DELAY);
566
- this.reconnectAttempts++;
567
- log.info(`Reconnecting in ${delay}ms (Attempt ${this.reconnectAttempts})`);
568
- setTimeout(async () => {
569
- try {
570
- await this.initServer();
571
- }
572
- catch (error) {
573
- log.warn('Reconnection failed', error);
574
- }
575
- }, delay);
576
451
  }
577
452
  async eventParse(eventData) {
578
453
  const notifyType = eventData.notify_type;
@@ -742,6 +617,10 @@ class Client extends EventEmitter {
742
617
  }
743
618
  }
744
619
  async postData(data) {
620
+ if (this.hasExpired) {
621
+ log.error('Token已到期,无法提供服务');
622
+ return;
623
+ }
745
624
  const config = {
746
625
  data: {
747
626
  guid: this.tokenInfo.guid,
@@ -1 +1 @@
1
- {"version":3,"file":"puppet-matrix.d.ts","sourceRoot":"","sources":["../../../src/puppet-matrix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"puppet-matrix.d.ts","sourceRoot":"","sources":["../../../src/puppet-matrix.ts"],"names":[],"mappings":"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"}
@@ -164,6 +164,12 @@ class PuppetMatrix extends PUPPET.Puppet {
164
164
  }, 5000);
165
165
  }
166
166
  }));
167
+ this._client.on('expired', this.wrapAsync(async (expired) => {
168
+ if (expired) {
169
+ log.info(PRE, 'Token has expired');
170
+ void this.onStop();
171
+ }
172
+ }));
167
173
  }
168
174
  addRunningPuppet(this);
169
175
  void this.checkIsLogin();
@@ -364,6 +370,8 @@ class PuppetMatrix extends PUPPET.Puppet {
364
370
  async _stopClient() {
365
371
  this.__currentUserId = undefined;
366
372
  this.__currentUserId = undefined;
373
+ this._client?.destroy();
374
+ this._client = undefined;
367
375
  if (this._cacheMgr) {
368
376
  log.info(PRE, 'colse cache');
369
377
  await this._cacheMgr.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wechaty-puppet-matrix",
3
- "version": "0.0.24",
3
+ "version": "0.0.27",
4
4
  "description": "Puppet matrix for Wechaty",
5
5
  "type": "module",
6
6
  "typings": "./dist/esm/src/mod.d.ts",
@@ -373,7 +373,7 @@ async function getAtWxidList (source: string): Promise<string[]> {
373
373
  }
374
374
 
375
375
  interface ConnectionStatus {
376
- status: 'disconnected' | 'connected' | 'connecting'
376
+ status: 'disconnected' | 'connected' | 'connecting' | 'reconnecting';
377
377
  }
378
378
 
379
379
  async function getImageInfo (imageUrl: string) {
@@ -637,17 +637,13 @@ class Client extends EventEmitter {
637
637
 
638
638
  private readonly options: PuppetMatrixOptions
639
639
  private connectionStatus: ConnectionStatus = { status: 'disconnected' }
640
- private readonly MAX_RECONNECT_ATTEMPTS = 10
641
- private readonly INITIAL_RECONNECT_DELAY = 1000 // 1秒
642
- private readonly MAX_RECONNECT_DELAY = 30000 // 30秒
643
- private readonly HEARTBEAT_INTERVAL = 40 * 1000 // 1分钟心跳间隔
644
- private readonly HEARTBEAT_TIMEOUT = 5000 // 5秒超时
645
- private reconnectAttempts = 0
646
640
  private heartbeatTimer?: any
641
+ private checkExpiredInterval?: any
647
642
  private heartbeatTimeoutTimer?: any
648
643
  private getQrcodeTimes = 0
649
644
  private restoreTimes = 0
650
645
  private maxRestoreTimes = 1
646
+ private hasExpired = false
651
647
  socket: any
652
648
  server: any
653
649
  tokenInfo: any
@@ -664,6 +660,7 @@ class Client extends EventEmitter {
664
660
  override emit(event: 'verify-code', verifyInfo: VerifyInfo): boolean;
665
661
  override emit(event: 'update-contacts', contacts: ContactPayload[]): boolean;
666
662
  override emit(event: 'room-join', info: any): boolean;
663
+ override emit(event: 'expired', info: boolean): boolean;
667
664
 
668
665
  override emit (event: ClientEvent, ...args: any[]): boolean {
669
666
  return super.emit(event, ...args)
@@ -684,6 +681,20 @@ class Client extends EventEmitter {
684
681
  this.getQrcodeTimes = 0
685
682
  this.restoreTimes = 0
686
683
  this.maxRestoreTimes = 1
684
+ this.hasExpired = false
685
+ }
686
+
687
+ destroy () {
688
+ log.verbose(PRE, 'destroy()')
689
+ this.hasEmitLogout = false
690
+ this.socket && this.socket.end()
691
+ this.socket = null
692
+ this.checkExpiredInterval && clearInterval(this.checkExpiredInterval)
693
+ this.checkExpiredInterval = undefined
694
+ this.heartbeatTimer && clearTimeout(this.heartbeatTimer)
695
+ this.heartbeatTimer = undefined
696
+ this.heartbeatTimeoutTimer && clearTimeout(this.heartbeatTimeoutTimer)
697
+ this.heartbeatTimeoutTimer = undefined
687
698
  }
688
699
 
689
700
  async getTokenInfo () {
@@ -691,6 +702,16 @@ class Client extends EventEmitter {
691
702
  const res = await axios.get(`https://api-bot.aibotk.com/openapi/v1/token/info?secret=5be06b6f8d42a7&token=${this.options.token}`)
692
703
  if (res.data.code === 0) {
693
704
  this.tokenInfo = res.data.data
705
+ this.hasExpired = res.data?.data?.hasExpired
706
+ if (this.hasExpired) {
707
+ log.error('Token已到期,请及时续费')
708
+ this.checkExpiredInterval && clearInterval(this.checkExpiredInterval)
709
+ this.checkExpiredInterval = undefined
710
+ setTimeout(() => {
711
+ this.emit('expired', true)
712
+ }, 3000)
713
+ return false
714
+ }
694
715
  return true
695
716
  } else {
696
717
  log.error('Token auth failed, reason: %s', res.data.message)
@@ -702,8 +723,16 @@ class Client extends EventEmitter {
702
723
  }
703
724
  }
704
725
 
726
+ checkHasExpired () {
727
+ this.checkExpiredInterval = setInterval(() => {
728
+ log.info('checkHasExpired')
729
+ void this.getTokenInfo()
730
+ }, 1000 * 60 * 60 * 12)
731
+ }
732
+
705
733
  async initServer () {
706
734
  await this.getTokenInfo()
735
+ this.checkHasExpired()
707
736
  if (this.socket) {
708
737
  log.error('socket had already been opened!')
709
738
  return
@@ -713,6 +742,9 @@ class Client extends EventEmitter {
713
742
  }
714
743
 
715
744
  async createMqttConnection (): Promise<void> {
745
+ if (this.hasExpired) {
746
+ return
747
+ }
716
748
  if (!this.tokenInfo) {
717
749
  log.error('Token info not available')
718
750
  return
@@ -734,12 +766,11 @@ class Client extends EventEmitter {
734
766
 
735
767
  client.on('connect', () => {
736
768
  this.connectionStatus.status = 'connected'
737
- this.reconnectAttempts = 0
738
769
  log.info('MQTT connection opened')
739
770
  this.socket = client
740
771
 
741
772
  // 订阅主题
742
- client.subscribe(`aibotk/msg/${this.tokenInfo.guid}`, (err) => {
773
+ client.subscribe(`aibotk/msg/${this.tokenInfo.guid}`, (err: any) => {
743
774
  if (err) {
744
775
  log.error('Failed to subscribe to topic', err)
745
776
  } else {
@@ -755,13 +786,14 @@ class Client extends EventEmitter {
755
786
  client.on('close', () => {
756
787
  this.connectionStatus.status = 'disconnected'
757
788
  log.warn('MQTT connection closed')
758
- this.socket = null
759
- void this.reconnect()
760
789
  })
761
790
 
762
- client.on('message', (topic, message) => {
763
- this.resetHeartbeatTimeout() // 收到任何消息都重置心跳超时
791
+ client.on('reconnect', () => {
792
+ this.connectionStatus.status = 'reconnecting'
793
+ log.warn('MQTT connection Reconnecting...')
794
+ })
764
795
 
796
+ client.on('message', (topic, message) => {
765
797
  log.verbose(PRE, 'Received message on topic %s: %s', topic, message.toString())
766
798
  if (message.toString() === 'ping' || message.toString() === 'pong') {
767
799
  log.verbose('Received heartbeat')
@@ -780,206 +812,6 @@ class Client extends EventEmitter {
780
812
  })
781
813
 
782
814
  this.socket = client
783
- this.startHeartbeat()
784
- }
785
-
786
- async createWebSocket (): Promise<void> {
787
- if (!this.tokenInfo) {
788
- log.error('Token info not available')
789
- return
790
- }
791
- const ws = new WebSocket(
792
- `${this.tokenInfo.endpoint}?guid=${this.tokenInfo.guid}`,
793
- {
794
- perMessageDeflate: true,
795
- maxPayload: 100 * 1024 * 1024,
796
- },
797
- )
798
-
799
- // 连接建立前的 Promise
800
- await new Promise<void>((resolve, reject) => {
801
- ws.once('open', () => {
802
- this.connectionStatus.status = 'connected'
803
- this.reconnectAttempts = 0
804
- log.info('WebSocket connection opened')
805
- resolve()
806
- })
807
-
808
- ws.once('error', (error: any) => {
809
- log.warn('WebSocket connection error', error)
810
- reject(error)
811
- })
812
-
813
- ws.once('close', (code: any, reason: any) => {
814
- void this.handleWebSocketClose(code, reason)
815
- reject(new Error(`WebSocket closed: ${code} - ${reason}`))
816
- })
817
- })
818
- this.socket = ws
819
-
820
- // 设置事件处理器
821
- this.setupWebSocketListeners(ws)
822
- }
823
-
824
- private setupWebSocketListeners (ws: WebSocket): void {
825
- // 消息处理
826
- ws.on('message', (data: string) => {
827
- this.resetHeartbeatTimeout() // 收到任何消息都重置心跳超时
828
- log.silly(PRE, 'initWebSocket() ws.on(message): %s', data)
829
- if (data.toString() === 'pong') {
830
- log.verbose('Received heartbeat')
831
- return
832
- }
833
- try {
834
- const payload = JSON.parse(data)
835
- log.info('Received payload', JSON.stringify(payload))
836
- void this.eventParse(payload)
837
- } catch (error) {
838
- log.warn(PRE, 'initWebSocket() ws.on(message) exception: %s', error)
839
- // @ts-ignore
840
- this.emit('error', (error as Error).message)
841
- }
842
- })
843
-
844
- // 错误处理
845
- ws.on('error', (error: Error) => {
846
- if ((error as any).code === 'ECONNREFUSED') {
847
- log.verbose('Connection refused, potential reconnect scenario')
848
- return
849
- }
850
-
851
- log.verbose(PRE, 'initWebSocket() ws.on(error) %s', error)
852
- // @ts-ignore
853
- this.emit('error', error)
854
- })
855
-
856
- // 关闭处理
857
- ws.on('close', (code:any, reason: any) => {
858
- this.stopHeartbeat()
859
- void this.handleWebSocketClose(code, reason)
860
- })
861
- // 启动心跳
862
- this.startHeartbeat()
863
- }
864
-
865
- private startHeartbeat (): void {
866
- this.stopHeartbeat() // 确保清理现有定时器
867
- this.heartbeatTimer = setInterval(() => {
868
- if (this.socket?.connected) {
869
- try {
870
- this.socket.publish(`aibotk/msg/${this.tokenInfo.guid}`, 'pong')
871
- this.setHeartbeatTimeout()
872
- } catch (error) {
873
- log.error('Failed to send heartbeat:', error)
874
- void this.handleMqttClose()
875
- }
876
- }
877
- }, this.HEARTBEAT_INTERVAL)
878
- }
879
-
880
- private stopHeartbeat (): void {
881
- if (this.heartbeatTimer) {
882
- // @ts-ignore
883
- clearInterval(this.heartbeatTimer)
884
- this.heartbeatTimer = undefined
885
- }
886
- if (this.heartbeatTimeoutTimer) {
887
- // @ts-ignore
888
- clearTimeout(this.heartbeatTimeoutTimer)
889
- this.heartbeatTimeoutTimer = undefined
890
- }
891
- }
892
-
893
- private setHeartbeatTimeout (): void {
894
- if (this.heartbeatTimeoutTimer) {
895
- // @ts-ignore
896
- clearTimeout(this.heartbeatTimeoutTimer)
897
- }
898
- this.heartbeatTimeoutTimer = setTimeout(() => {
899
- log.warn('Heartbeat timeout, reconnecting...')
900
- void this.handleMqttClose()
901
- }, this.HEARTBEAT_TIMEOUT)
902
- }
903
-
904
- private resetHeartbeatTimeout (): void {
905
- if (this.heartbeatTimeoutTimer) {
906
- // @ts-ignore
907
- clearTimeout(this.heartbeatTimeoutTimer)
908
- this.heartbeatTimeoutTimer = undefined
909
- }
910
- }
911
-
912
- private async handleMqttClose () {
913
- this.connectionStatus.status = 'disconnected'
914
- log.warn('MQTT connection closed')
915
- if (this.socket) {
916
- this.socket.end()
917
- this.socket = null
918
- }
919
-
920
- // 触发重连
921
- await this.reconnectMqtt()
922
- }
923
-
924
- private async reconnectMqtt (): Promise<void> {
925
- if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
926
- log.error('Max reconnect attempts reached. Stopping reconnection.')
927
- return
928
- }
929
-
930
- // 指数退避重连策略
931
- const delay = Math.min(
932
- this.INITIAL_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts),
933
- this.MAX_RECONNECT_DELAY,
934
- )
935
-
936
- this.reconnectAttempts++
937
- log.info(`Reconnecting in ${delay}ms (Attempt ${this.reconnectAttempts})`)
938
- setTimeout(() => {
939
- try {
940
- void this.createMqttConnection()
941
- } catch (error) {
942
- log.warn('Reconnection failed', error)
943
- }
944
- }, delay)
945
- }
946
-
947
- private async handleWebSocketClose (code?: number, reason?: Buffer | String) {
948
- this.connectionStatus.status = 'disconnected'
949
- log.warn(`WebSocket closed: Code ${code}, Reason ${reason}`)
950
- if (this.socket) {
951
- this.socket.close()
952
- this.socket = null
953
- }
954
-
955
- // 触发重连
956
- await this.reconnect()
957
-
958
- }
959
-
960
- private async reconnect (): Promise<void> {
961
- if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
962
- log.error('Max reconnect attempts reached. Stopping reconnection.')
963
- return
964
- }
965
-
966
- // 指数退避重连策略
967
- const delay = Math.min(
968
- this.INITIAL_RECONNECT_DELAY * Math.pow(2, this.reconnectAttempts),
969
- this.MAX_RECONNECT_DELAY,
970
- )
971
-
972
- this.reconnectAttempts++
973
- log.info(`Reconnecting in ${delay}ms (Attempt ${this.reconnectAttempts})`)
974
-
975
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
976
- setTimeout(async () => {
977
- try {
978
- await this.initServer()
979
- } catch (error) {
980
- log.warn('Reconnection failed', error)
981
- }
982
- }, delay)
983
815
  }
984
816
 
985
817
  async eventParse (eventData: any) {
@@ -1179,6 +1011,10 @@ class Client extends EventEmitter {
1179
1011
  }
1180
1012
 
1181
1013
  async postData (data: any) {
1014
+ if (this.hasExpired) {
1015
+ log.error('Token已到期,无法提供服务')
1016
+ return
1017
+ }
1182
1018
  const config: any = {
1183
1019
  data: {
1184
1020
  guid: this.tokenInfo.guid,