目录

如何实现TcpSocket断开重连

问题现象

TcpSocket异常断开连接后,如何实现循环重连?

背景知识

建立TcpSocket连接前,需要通过constructTCPSocketInstance创建tcp实例,然后才能调用connect接口连接指定tcp服务。若是TcpSocket异常断开,需调用close接口销毁之前的实例,然后重新创建TcpSocket实例,调用connect接口尝试重连。

解决方案

TcpSocket不具备自动回连机制,开发者需要通过业务逻辑实现循环重连,具体实现可参考如下代码:

import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct TcpSocketReconnect {
  // 1.tcpSocket实例
  @State tcpSocket: socket.TCPSocket | null = null;

  // 2.创建socket实例
  createSocket() {
    this.tcpSocket = socket.constructTCPSocketInstance();
    this.registerEvents();
  }

  // 3.注册事件监听
  registerEvents() {
    this.tcpSocket?.on('close', () => {
      console.info('Connection closed');
      // 获取当前tcpSocket连接状态
      this.tcpSocket?.getState((err: BusinessError, data: socket.SocketStateBase) => {
        if (err) {
          console.error('getState fail');
          return;
        }
        console.info('getState success:', JSON.stringify(data));
        // 如果tcpSocket未关闭连接,释放旧连接,然后开始重连
        // 如果tcpSocket已关闭连接,说明用户需要主动断开,无需重连
        if (data.isConnected) {
          try {
            this.tcpSocket?.close();
          } catch (err) {
            console.error('Close error:', JSON.stringify(data));
          }
          // 触发重连。注:此处应根据开发者业务所需,判断是否需要触发重连
          this.reconnect();
        }
      });
    });

    this.tcpSocket?.on('error', (err: BusinessError) => {
      console.error('Error occurred:', JSON.stringify(err));
      this.reconnect(); // 错误时触发重连
    });
  }

  // 4.实现重连逻辑
  reconnect() {
    console.info('Reconnecting...');
    // 创建新连接
    this.createSocket();
    this.connectToServer();

  }

  // 5.建立连接
  connectToServer() {
    let address: socket.NetAddress = {
      address: '36.137.xxx.xxx',
      port: 8080
    };
    this.tcpSocket?.connect({ address, timeout: 5000 }, (err: BusinessError) => {
      if (err) {
        console.error('Connect failed:', JSON.stringify(err));
        return;
      }
      console.info('Connect success');
    });
  }

  build() {
    Column() {
      Button('初始化实例/创建回连机制').onClick(() => {
        // 初始化实例/创建回连机制
        this.createSocket();
      }).margin(15);
      Button('建立连接').onClick(() => {
        // 建立连接
        this.connectToServer();
      });
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.SpaceAround);
  }
}