纯 4g 或纯 wifi 下 websocket 都是正常连接的,但只要 wifi 和 4g 网络两个链路都联通就不行,http 请求没这个问题,用的是你们官方封装的 websocket client:T5_TuyaOS-3.13.8/software/TuyaOS/include/components/lib_websocket/include/websocket_client.h
T5 3.13.8,只要 wifi 和 4g 网络两个链路都联通,websocket 就无法连接,麻烦修复下吧
Re: T5 3.13.8,只要 wifi 和 4g 网络两个链路都联通,websocket 就无法连接,麻烦修复下吧
结论:这不是网络问题,是 lib_websocket 组件不支持多链路——双链路同时在线时,它创建的 socket 没绑定到 active 链路的本机 IP,路由/源地址错配导致 TCP connect 失败;单链路下不存在选路问题,所以纯 WiFi、纯 4G 都正常。
原理
- T5 双链路由
svc_netmgrlinkage 管理,两条链路同时 up 时协议栈里有两个接口(WiFi netif + CAT1 PPP netif),未绑定 socket 走哪条链路、用哪个源 IP 由默认路由决定,不受控。 - 官方 svc 层组件在此场景都会显式绑定链路:以 netmgr daemon 的探测连接为例,先
linkage->get(LINKAGE_CFG_IP)取 active 链路 IP,再SET_TCP_CONFIG把bindAddr设成该 IP 后才 connect(svc_netmgr/README_CN.md§7.6)。MQTT/HTTP 走的是这类链路感知通道,所以 HTTP 没问题。 lib_websocket是独立客户端组件,websocket_client_cfg_t.tcpConfig只是透传给底层 transporter,内部不设bindAddr,也不监听链路切换 → 双链路下 connect 反复失败,task 每 5 秒重连。
应用侧规避(3.13.8 直接可用)
Code: Select all
// 1. 取 active 链路(按优先级选出的那条)的本机 IP
NW_IP_S ip = {0};
LINKAGE_IF_S *lf = tuya_svc_netmgr_linkage_get(LINKAGE_TYPE_DEFAULT);
if (lf) { lf->get(LINKAGE_CFG_IP, &ip); }
// 2. websocket 初始化时绑定到该链路
websocket_client_cfg_t cfg = {0};
cfg.uri = "wss://your.host.com/path";
cfg.tcpConfig.cacert = ca_pem;
cfg.tcpConfig.bindAddr = tal_net_str2addr(ip.ip); // 关键一行
websocket_client_init(&h, &cfg);
websocket_client_start(h, "ws_task");两个注意点:
bindAddr在 init 时注入,内部 5s 自动重连沿用旧 transporter。链路切换后(daemon 会切默认链路并清 DNS 缓存)需websocket_client_close()再按新 active 链路 IP 重新 init/start。- 若日志里是 DNS 失败(
custom dns fail/-0x7102)而非 connect 失败,同样先加绑定再看——未绑定 socket 的 DNS 查询在双链路下也可能走错链路。
SDK 侧:这个会反馈给基线,让 lib_websocket 在多链路场景自动取 active 链路 IP 绑定、并在链路切换后自动重建连接。升级基线版本前,先用上面的规避方案。
出处:kb/network/20260513-backup-network-design.md(备份网络三层设计)、components/svc_netmgr/README_CN.md §7.6(daemon 探测连接的 bindAddr 用法)、components/lib_websocket/README_CN.md(tcpConfig 透传与 5s 重连机制)。
以上内容由 AI 自动分析生成,如有疑问请回复补充。