更新记录
1.0.1(2026-04-27)
- 新增 Harmony App 支持。
- 更新平台支持信息、权限说明与 playground 测试默认地址。
1.0.0(2026-02-06)
- 首次发布。
- 支持 TCP 客户端:连接、发送、接收、关闭。
- 支持 UDP:绑定、发送、接收、broadcast 开关。
- 支持字符串与 ArrayBuffer 两种数据类型。
- 提供统一错误码、日志控制与基础编解码工具。
平台兼容性
uni-app(5.07)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
- |
- |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| - |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
uni-app x(5.07)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| - |
- |
√ |
√ |
√ |
- |
其他
| 多语言 |
暗黑模式 |
宽屏模式 |
蒸汽模式 |
| × |
× |
× |
√ |
hans-socket
App 端 UTS Socket 插件,提供 TCP 客户端与 UDP 通信能力,适用于设备通信、局域网发现、网关控制等场景。
下载与安装
- 打开 HBuilderX → 插件市场 → 搜索
hans-socket。
- 点击“导入插件”,插件会进入项目
uni_modules/hans-socket。
- 在页面
script 中引入 API。
平台支持
| 平台 |
TCP |
UDP |
说明 |
| Android |
√ |
√ |
支持 broadcast;可选 androidMulticastLock |
| iOS |
√ |
√ |
支持 broadcast(受系统/网络环境限制) |
| Harmony |
√ |
√ |
基于 @kit.NetworkKit Socket;broadcast/局域网访问受系统与网络环境限制 |
Harmony 侧为 UTS + ArkTS/ETS 混编实现;框架支持(uni-app / uni-app x)请以当前插件 package.json 的 uni_modules.platforms 为准。
推荐使用流程
createTcpSocket / createUdpSocket 创建实例(拿到 socketId)。
- 立刻注册
onOpen/onMessage/onClose/onError(或 UDP 对应事件)。
- TCP 走
tcpConnect,UDP 走 udpBind(按需 udpSetBroadcast)。
- 收发数据(文本 /
ArrayBuffer / bytesMessage)。
- 页面离开时调用
tcpClose / udpClose 回收资源。
快速开始(uni-app x)
<script setup lang="uts">
import {
createTcpSocket,
tcpConnect,
tcpSendText,
tcpOnOpen,
tcpOnMessage,
tcpOnError,
tcpOnClose,
tcpClose,
createUdpSocket,
udpBind,
udpSetBroadcast,
udpSendTextTo,
udpOnListening,
udpOnMessage,
udpOnError,
udpOnClose,
udpClose
} from '@/uni_modules/hans-socket'
let tcpId: number = 0
let udpId: number = 0
function startTcp() {
tcpId = createTcpSocket({ receiveType: 'string', encoding: 'utf-8' })
tcpOnOpen(tcpId, () => tcpSendText(tcpId, 'hello'))
tcpOnMessage(tcpId, (res) => console.log('tcp.message', res.data ?? res.buffer))
tcpOnError(tcpId, (err) => console.error('tcp.error', err.errCode, err.errMsg))
tcpOnClose(tcpId, (res) => { console.log('tcp.close', res.hadError); tcpId = 0 })
tcpConnect(tcpId, '127.0.0.1', 9000, 15000)
}
function startUdp() {
udpId = createUdpSocket({ receiveType: 'string', encoding: 'utf-8', enableBroadcast: true })
udpOnListening(udpId, () => console.log('udp.listening'))
udpOnMessage(udpId, (res) => console.log('udp.message', res.address, res.port, res.data ?? res.buffer))
udpOnError(udpId, (err) => console.error('udp.error', err.errCode, err.errMsg))
udpOnClose(udpId, () => { udpId = 0 })
udpSetBroadcast(udpId, true)
udpBind(udpId, { port: 7779, address: '0.0.0.0', reuseAddress: true, androidMulticastLock: false })
udpSendTextTo(udpId, '127.0.0.1', 7777, 'ping')
}
function destroyAll() {
if (tcpId != 0) tcpClose(tcpId)
if (udpId != 0) udpClose(udpId)
}
</script>
快速开始(uni-app)
<script setup>
import { ref } from 'vue'
import { onUnload } from '@dcloudio/uni-app'
import {
createTcpSocket,
tcpConnect,
tcpSendText,
tcpOnOpen,
tcpOnMessage,
tcpOnError,
tcpClose,
createUdpSocket,
udpBind,
udpSendTextTo,
udpOnMessage,
udpSetBroadcast,
udpClose
} from '@/uni_modules/hans-socket'
const tcpId = ref(0)
const udpId = ref(0)
function startTcp() {
if (tcpId.value !== 0) return
tcpId.value = createTcpSocket({ receiveType: 'string', encoding: 'utf-8' })
tcpOnOpen(tcpId.value, () => tcpSendText(tcpId.value, 'hello'))
tcpOnMessage(tcpId.value, (res) => console.log('tcp.message', res.data ?? res.buffer))
tcpOnError(tcpId.value, (err) => console.error('tcp.error', err.errCode, err.errMsg))
tcpConnect(tcpId.value, '127.0.0.1', 9000, 15000)
}
function startUdp() {
if (udpId.value !== 0) return
udpId.value = createUdpSocket({ receiveType: 'string', encoding: 'utf-8', enableBroadcast: true })
udpSetBroadcast(udpId.value, true)
udpBind(udpId.value, { port: 7779, address: '0.0.0.0', reuseAddress: true })
udpOnMessage(udpId.value, (res) => console.log('udp.message', res.address, res.port, res.data ?? res.buffer))
udpSendTextTo(udpId.value, '127.0.0.1', 7777, 'ping')
}
onUnload(() => {
if (tcpId.value !== 0) tcpClose(tcpId.value)
if (udpId.value !== 0) udpClose(udpId.value)
})
</script>
进阶用法(来自 playground 实战)
1) bytesMessage 发包
bytesMessage 是 JSON 字符串,内容为字节数组(数字或十六进制字符串):
// 数字数组
tcpSendBytesMessage(tcpId, '[1,2,3,4]')
// 16 进制字符串数组
const payload = JSON.stringify(['53', '53', '01', 'c0', '00', 'A9'])
udpSendBytesMessageTo(udpId, '127.0.0.1', 7777, payload)
2) 指定本地端口发送 UDP
udpSendTextToFromPort(udpId, '192.168.1.100', 7777, 9527, 'hello')
udpSendBytesMessageToFromPort(udpId, '192.168.1.100', 7777, 9527, '[0,1,2,3]')
3) 先发送再绑定(同一 UDP socket)
playground 已验证 send-only -> bind -> receive 流程,可用于某些“先探测后监听”场景。
4) 二进制调试
const hex = arrayBufferToHex(buffer, false)
const ab = bytesMessageToArrayBuffer('[9,8,7,6]')
API 一览
TCP
createTcpSocket(options?)
tcpConnect(id, host, port, timeoutMs?)
tcpSendText(id, data) / tcpSendBuffer(id, buffer) / tcpSendBytesMessage(id, bytesMessage)
tcpClose(id)
tcpOnOpen(id, callback)
tcpOnMessage(id, callback)
tcpOnClose(id, callback)
tcpOnError(id, callback)
tcpGetState(id)
UDP
createUdpSocket(options?)
udpBind(id, options)
udpSendTextTo(id, address, port, data)
udpSendBufferTo(id, address, port, buffer)
udpSendBytesMessageTo(id, address, port, bytesMessage)
udpSendTextToFromPort(id, address, port, localPort, data)
udpSendBufferToFromPort(id, address, port, localPort, buffer)
udpSendBytesMessageToFromPort(id, address, port, localPort, bytesMessage)
udpSetBroadcast(id, enabled)
udpClose(id)
udpOnListening(id, callback)
udpOnMessage(id, callback)
udpOnClose(id, callback)
udpOnError(id, callback)
工具函数
setLogEnabled(enabled) / isLogEnabled()
arrayBufferToHex(buffer, uppercase?)
hexToArrayBuffer(hex)
bytesMessageToArrayBuffer(bytesMessage)
关键参数说明
receiveType: 'string' | 'arraybuffer',默认 'string'。
encoding: 默认 utf-8。playground 示例包含 utf-8 / ascii / iso-8859-1 / gbk / gb18030;Harmony 侧优先建议 utf-8/ascii/iso-8859-1,复杂中文编码建议使用 ArrayBuffer 自行编解码。
UdpBindOptions.port: 监听端口,取值范围 1 ~ 65535。
UdpBindOptions.address: 监听地址,常用 0.0.0.0。
UdpBindOptions.reuseAddress: 端口复用(不同系统语义可能有差异)。
UdpBindOptions.androidMulticastLock: Android 下优化 broadcast/multicast 收包。
权限说明
Android
- 必需:
INTERNET
- 可选(broadcast/multicast 场景):
CHANGE_WIFI_MULTICAST_STATE、ACCESS_WIFI_STATE
iOS
- iOS 14+ 局域网访问需要 Local Network 授权(
NSLocalNetworkUsageDescription)
Harmony
- 必需:
ohos.permission.INTERNET(插件已在 utssdk/app-harmony/module.json5 声明)
- UDP broadcast / 局域网发现仍可能受设备网络、系统权限策略与路由器隔离策略影响。
使用注意
- 同一 socket 的同一事件(
tcpOn* / udpOn*)重复注册会覆盖上一次回调。
receiveType='string' 时读取 res.data;receiveType='arraybuffer' 时读取 res.buffer。
- TCP 是字节流,
message 回调不等于业务消息边界,请自行做拆包/粘包。
- Android 模拟器访问宿主机建议使用
10.0.2.2(playground 已按此处理默认值);iOS 模拟器通常可用 127.0.0.1;Harmony 真机访问 Mac 测试服务需使用 Mac 局域网 IP(本次测试服务为 192.168.10.144)。
- 页面销毁/退出时务必调用
tcpClose / udpClose。
错误码
9020101 NOT_SUPPORTED
9020102 INVALID_ARGUMENT
9020103 INVALID_STATE
9020104 UNSUPPORTED_ENCODING
9020201 TCP_CONNECT_FAILED
9020202 TCP_SEND_FAILED
9020203 TCP_RECEIVE_FAILED
9020204 TCP_TIMEOUT
9020301 UDP_CREATE_FAILED
9020302 UDP_BIND_FAILED
9020303 UDP_SEND_FAILED
9020304 UDP_RECEIVE_FAILED
9020999 UNKNOWN