uni-app无法直接使用TCP/UDP,仅WebSocket在H5端支持局域网连接;App端需通过原生插件实现,小程序端必须经HTTPS中转。
uni-app 里没法直接用 WebSocket 或 net.Socket 做 TCP/UDP
uni-app 的 js 运行环境是 webview(ios/android)或小程序逻辑层,不暴露原生网络套接字 api。你写 new websocket('ws://...') 可以,但 require('net') 或 udp.createsocket() 在任何端都会报错——不是语法问题,是根本没这层能力。
常见错误现象:Cannot find module 'net'、ReferenceError: udp is not defined、真机调试时 WebSocket 连内网 IP 失败(被平台拦截或跨域策略拒绝)。
- 小程序端:只允许 HTTPS/WSS,且域名必须在后台配置白名单,
192.168.x.x这类局域网地址直接被微信/支付宝引擎丢弃 - H5 端:WebSocket 可连局域网 IP,但需服务端开启 CORS,且浏览器可能因混合内容(HTTP 页面连 HTTP WS)静默阻断
- App 端(vue-cli 模式):可通过
nativePlugin调用原生 UDP/TCP,但@dcloudio/uni-app官方编译模式下不支持
App 端走原生插件调 UDP/TCP 是唯一可行路径
如果你目标是安卓/iOS App(非小程序/H5),必须绕过 JS 层限制,用原生能力封装通信逻辑。uni-app 提供了 uni.requireNativePlugin 机制加载自定义原生模块。
使用场景:控制智能硬件(如 ESP32、树莓派)、局域网打印机、串口转 WiFi 模块等,需要发 UDP 广播包发现设备,或建 TCP 长连接收发二进制指令。
- 安卓需写 Java/Kotlin 插件,用
DatagramSocket/Socket实现;iOS 用 Objective-C/Swift 封装GCDAsyncUdpSocket/NSTCPConnection - 插件方法名要统一,比如
sendUdpBroadcast(data, port)、connectTcp(host, port),JS 层只负责传参和监听回调 - 注意 Android 10+ 对明文 HTTP/UDP 的限制:
android:usesCleartextTraffic="true"必须显式声明,否则发包无声无息失败 - 别把大文件塞进 UDP 包——MTU 通常 1500 字节,超长会被丢弃,也不要做重传逻辑,那是原生层该干的事
小程序端只能妥协:改用 HTTP + 后台中转
小程序彻底封死直连局域网的能力,想“发现设备”或“发指令”,唯一合规方式是让设备自带 HTTP Server(比如 ESP8266 启一个轻量 Web 服务),再通过云函数或自有服务器做代理转发。
常见错误现象:调用 uni.request({ url: 'http://192.168.1.100/control' }) 直接返回 errCode: -1004(网络请求失败),控制台无具体错误,因为请求压根没发出。
- 设备端 HTTP 接口必须支持 CORS,响应头加
Access-Control-Allow-Origin: *(仅开发期,上线建议精确域名) - 真机调试时,确保手机和设备在同一 WiFi 下,且路由器未开启 AP 隔离(否则设备间 ping 不通)
- 不要依赖
uni.getNetworkType判断是否在局域网——它只返回 wifi/4g,不告诉你连的是哪个 SSID - 若设备无法改固件加 HTTP 服务,这条路就走不通,别浪费时间调接口
跨端统一?不存在的,得按端拆逻辑
同一个页面里写一套代码覆盖 App/H5/小程序?不可能。三端网络能力差异是底层决定的,强行抽象只会让 bug 更隐蔽。
性能与兼容性影响:H5 用 WebSocket 连局域网设备延迟最低(毫秒级),App 插件次之(有跨进程开销),小程序最差(必须经公网中转,至少增加 100ms+ RTT)。
- 用
process.env.UNI_PLATFORM做条件判断:值为app-plus/h5/mp-weixin,分别引入不同通信模块 - 别在
onLoad里直接初始化连接——小程序可能还没获取到网络状态,先uni.getNetworkType+setTimeout等 300ms 再连 - UDP 广播搜设备时,App 插件可设超时 3 秒,H5 用 WebSocket 就得靠心跳探测,小程序只能轮询 HTTP 接口,节奏必须区分开
真正麻烦的从来不是怎么发一个包,而是设备掉线后怎么感知、重连间隔怎么设、二进制协议怎么解析又不卡 UI 线程——这些细节,原生插件和前端 JS 得各管一段,谁也别指望另一端兜底。










