+
13
-

如何实现uni.connectSocket兼容web与小程序app端的websocket通讯?

如何实现uni.connectSocket兼容web与小程序app端的websocket通讯?


网友回复

+
2
-

要在 uni-app 中实现兼容 Web、小程序及 App 端的 WebSocket 通信,核心在于使用 uni.connectSocket API,并针对不同平台的特性和限制进行适配。以下将提供一个详细的实现方案,包括封装可重用的 WebSocket 模块、心跳机制、自动重连以及各端兼容性处理。

核心 API:uni.connectSocket

uni-app 框架提供了一套兼容多端的 WebSocket API,主要包括:

uni.connectSocket(OBJECT): 创建一个 WebSocket 连接,返回一个 SocketTask 对象。

SocketTask.onOpen(CALLBACK): 监听 WebSocket 连接打开事件。

SocketTask.onMessage(CALLBACK): 监听 WebSocket 接收到服务器的消息事件。

SocketTask.onError(CALLBACK): 监听 WebSocket 错误事件。

SocketTask.onClose(CALLBACK): 监听 WebSocket 连接关闭事件。

SocketTask.send(OBJECT): 通过 WebSocket 连接发送数据。

SocketTask.close(OBJECT): 关闭 WebSocket 连接。

官方建议使用 SocketTask 对象来处理 WebSocket 相关事件,因为它提供了更精细的控制,尤其是在需要管理多个连接或复杂交互的场景中。

封装通用的 WebSocket 模块

为了方便在项目中复用,强烈建议将 WebSocket 的逻辑封装成一个独立的模块。这不仅能让代码更清晰,也便于集中处理多端兼容问题、心跳和重连逻辑。

以下是一个封装的 websocket.js 模块示例,它包含了连接、心跳检测、断线重连等核心功能:

// websocket.js
class WebSocketService {
  constructor(url, heartBeatConfig = {}) {
    this.url = url;
    this.socketTask = null;
    this.isReconnecting = false;
    this.reconnectTimer = null;
    this.heartBeatTimer = null;
    this.userClose = false; // 用户主动关闭

    // 心跳配置
    this.heartBeat = {
      interval: 30000, // 心跳间隔,单位ms
      pingData: 'ping', // 心跳请求消息
      ...heartBeatConfig,
    };

    this.connect();
  }

  // 连接
  connect() {
    if (this.socketTask && this.socketTask.readyState === 1) {
      return;
    }
    this.userClose = false;
    this.socketTask = uni.connectSocket({
      url: this.url,
      success: () => {
        console.log('WebSocket 正在连接...');
      },
      fail: (err) => {
        console.error('WebSocket 连接失败:', err);
        this.reconnect();
      },
    });

    this.initEventListeners();
  }

  // 初始化事件监听
  initEventListeners() {
    if (!this.socketTask) return;

    this.socketTask.onOpen(() => {
      console.log('WebSocket 连接已打开!');
      this.isReconnecting = false;
      this.startHeartBeat();
      // 连接成功后可以触发一个全局事件或回调
      uni.$emit('onSocketOpen');
    });

    this.socketTask.onMessage((res)...

点击查看剩余70%

我知道答案,我要回答