更新记录
1.0.0(2026-02-06)
- 首次发布。
- 支持 TCP 客户端:连接、发送、接收、关闭。
- 支持 UDP:绑定、发送、接收、broadcast 开关。
- 支持字符串与 ArrayBuffer 两种数据类型。
- 提供统一错误码、日志控制与基础编解码工具。
平台兼容性
uni-app(4.87)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | √ | √ | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.87)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | √ | - | - |
hans-socket
App 端 UTS Socket 插件,提供 TCP 客户端与 UDP 通信能力,适用于设备通信、局域网发现、网关控制等场景。
本 README 的示例来自仓库内两个页面(API 一致):
uniappx-socket-playground/pages/socket/socket.uvue(uni-app x)uniapp-socket-playground/pages/socket/socket.vue(uni-app)
下载与安装
- 打开 HBuilderX → 插件市场 → 搜索
hans-socket。 - 点击“导入插件”,插件会进入项目
uni_modules/hans-socket。 - 在页面
script中引入 API。
平台支持
| 平台 | TCP | UDP | 说明 |
|---|---|---|---|
| Android | √ | √ | 支持 broadcast;可选 androidMulticastLock |
| iOS | √ | √ | 支持 broadcast(受系统/网络环境限制) |
| Harmony | - | - | 调用返回 9020101 NOT_SUPPORTED |
框架支持(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。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)
使用注意
- 同一 socket 的同一事件(
tcpOn* / udpOn*)重复注册会覆盖上一次回调。 receiveType='string'时读取res.data;receiveType='arraybuffer'时读取res.buffer。- TCP 是字节流,
message回调不等于业务消息边界,请自行做拆包/粘包。 - Android 模拟器访问宿主机建议使用
10.0.2.2(playground 已按此处理默认值)。 - 页面销毁/退出时务必调用
tcpClose/udpClose。
错误码
9020101NOT_SUPPORTED9020102INVALID_ARGUMENT9020103INVALID_STATE9020104UNSUPPORTED_ENCODING9020201TCP_CONNECT_FAILED9020202TCP_SEND_FAILED9020203TCP_RECEIVE_FAILED9020204TCP_TIMEOUT9020301UDP_CREATE_FAILED9020302UDP_BIND_FAILED9020303UDP_SEND_FAILED9020304UDP_RECEIVE_FAILED9020999UNKNOWN

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 239
赞赏 0
下载 11245327
赞赏 1856
赞赏
京公网安备:11010802035340号