> 技术文档 > uniapp在APP上如何使用websocket--详解_uniapp websocket

uniapp在APP上如何使用websocket--详解_uniapp websocket


UniApp 在 APP 端如何使用 WebSocket以及常见问题

一、WebSocket 基础概念

WebSocket 是一种在单个TCP连接上进行全双工通信的协议,适用于实时数据传输场景(如聊天室、实时游戏、股票行情等)。

与传统HTTP对比

特性 WebSocket HTTP 连接方式 长连接 短连接 通信方向 全双工 半双工 数据格式 二进制/文本 文本 首部大小 2-10字节 8000+字节

二、UniApp 中使用 WebSocket

1. API 概览

UniApp 封装了微信小程序风格的 WebSocket API:

  • uni.connectSocket() - 创建连接
  • uni.onSocketOpen() - 监听连接打开
  • uni.onSocketError() - 监听错误
  • uni.sendSocketMessage() - 发送消息
  • uni.onSocketMessage() - 接收消息
  • uni.closeSocket() - 关闭连接
  • uni.onSocketClose() - 监听关闭

2. 完整使用示例

// websocket.jslet socketTask = null;let reconnectAttempts = 0;const maxReconnectAttempts = 5;export function connectWebSocket() { return new Promise((resolve, reject) => { const url = \'wss://your-websocket-server.com\'; // 创建连接 socketTask = uni.connectSocket({ url: url, success: () => { console.log(\'WebSocket 连接创建中...\'); }, fail: (err) => { console.error(\'连接创建失败:\', err); reject(err); } }); // 监听打开事件 socketTask.onOpen((res) => { console.log(\'WebSocket 连接已打开\'); reconnectAttempts = 0; resolve(socketTask); }); // 监听错误事件 socketTask.onError((err) => { console.error(\'WebSocket 错误:\', err); handleReconnection(); reject(err); }); // 监听关闭事件 socketTask.onClose((res) => { console.log(\'WebSocket 连接已关闭\', res); if (!res.code === 1000) { // 非正常关闭 handleReconnection(); } }); });}function handleReconnection() { if (reconnectAttempts < maxReconnectAttempts) { reconnectAttempts++; const delay = Math.min(1000 * reconnectAttempts, 5000); console.log(`尝试第 ${reconnectAttempts} 次重连,${delay}ms后执行`); setTimeout(() => { connectWebSocket().catch(console.error); }, delay); } else { console.error(`已达到最大重连次数 ${maxReconnectAttempts}`); }}// 发送消息export function sendWebSocketMessage(message) { return new Promise((resolve, reject) => { if (!socketTask || socketTask.readyState !== 1) { reject(\'WebSocket 未连接\'); return; } socketTask.send({ data: JSON.stringify(message), success: () => resolve(), fail: (err) => reject(err) }); });}// 关闭连接export function closeWebSocket() { if (socketTask) { socketTask.close({ code: 1000, reason: \'用户主动关闭\' }); }}

3. 心跳机制实现

let heartbeatTimer = null;function startHeartbeat() { // 每30秒发送一次心跳 heartbeatTimer = setInterval(() => { sendWebSocketMessage({ type: \'heartbeat\', timestamp: Date.now() }).catch(() => { clearInterval(heartbeatTimer); }); }, 30000);}// 在onOpen中调用socketTask.onOpen(() => { startHeartbeat();});// 在onClose中清除socketTask.onClose(() => { clearInterval(heartbeatTimer);});

4. 消息队列处理

当网络不稳定时,可实现消息队列:

let messageQueue = [];let isSending = false;async function processQueue() { if (isSending || messageQueue.length === 0) return; isSending = true; const message = messageQueue.shift(); try { await sendWebSocketMessage(message); } catch (err) { messageQueue.unshift(message); // 重新放回队列 } finally { isSending = false; processQueue(); }}export function queueMessage(message) { messageQueue.push(message); processQueue();}

三、注意事项

  1. 平台差异

    • iOS 对后台WebSocket连接限制严格
    • 部分安卓机型可能在锁屏后断开连接
  2. 安全要求

    • 必须使用wss协议(SSL加密)
    • 建议实现消息加密(如AES)
  3. 性能优化

    • 大数据量传输建议使用ArrayBuffer
    • 避免频繁发送小消息(可合并发送)
  4. 调试技巧

    // 开启调试模式uni.setEnableDebug({ enableDebug: true});

四、完整页面示例

<template> <view class=\"container\"> <button @click=\"connect\">连接WebSocket</button> <button @click=\"send\">发送测试消息</button> <button @click=\"close\">关闭连接</button> <scroll-view scroll-y class=\"message-box\"> <view v-for=\"(msg, index) in messages\" :key=\"index\"> {{ msg }} </view> </scroll-view> </view></template><script>import { connectWebSocket, sendWebSocketMessage, closeWebSocket } from \'@/utils/websocket\';export default { data() { return { messages: [], socketTask: null } }, onUnload() { closeWebSocket(); }, methods: { async connect() { try { this.socketTask = await connectWebSocket(); this.socketTask.onMessage((res) => { this.messages.push(\'收到消息: \' + res.data); }); this.messages.push(\'WebSocket 已连接\'); } catch (err) { this.messages.push(\'连接失败: \' + err); } }, async send() { try { await sendWebSocketMessage({ type: \'test\', content: \'Hello WebSocket\', timestamp: Date.now() }); this.messages.push(\'消息已发送\'); } catch (err) { this.messages.push(\'发送失败: \' + err); } }, close() { closeWebSocket(); this.messages.push(\'已主动关闭连接\'); } }}</script><style>.container { padding: 20px;}.message-box { height: 300px; margin-top: 20px; border: 1px solid #eee; padding: 10px;}</style>

五、常见问题解决

Q1: 安卓设备连接不稳定

  • 解决方案:在manifest.json中配置:

    \"app-plus\": { \"keepRunning\": true, \"optimization\": { \"keepAlive\": true }}

Q2: iOS后台断连

  • 解决方案:启用后台模式(需在manifest.json中声明):

    \"ios\": { \"UIBackgroundModes\": [\"audio\"]}

    并通过心跳保持活跃

Q3: 真机调试无法连接

  • 检查项:
    1. 是否使用HTTPS/WSS
    2. 域名是否加入白名单
    3. 手机网络是否正常

Q4: 如何发送二进制数据

// 发送ArrayBufferconst buffer = new ArrayBuffer(8);socketTask.send({ data: buffer, fail: console.error});