一、WebSocket为什么选择TCP不用UDPWebSocket是建立在TCP之上的应用层协议底层骨架就是TCP。WebSocket场景网页/前端和PHPSwoole/Hyperf服务端双向实时通信比如聊天、消息推送、监控面板。TCP就像有签收回执的快递专线包裹有序送达、丢件自动补发、不会收到重复乱序消息。UDP就像平信没有签收发出去就不管有没有送到。如果WebSocket用UDP会遇到几个致命问题消息乱序消息先发的后到聊天消息顺序颠倒业务层要自己写复杂的排序逻辑。丢包无感知推送一条通知半路丢了服务端不知道前端没收着业务要自己做ACK、重传。没有连接身份UDP无连接很难识别同一个用户持续会话。穿透防火墙麻烦大部分防火墙对UDP限制更严格网页端浏览器对UDP原生支持弱WebRTC才用UDP。WebSocket业务需要可靠、有序的双向数据流TCP已经把ACK确认、重传、流量控制、拥塞控制全部在内核做好开发者只需要读写消息不用自己实现可靠传输所以直接复用TCP。补充WebRTC是浏览器实时音视频才用UDPQUIC因为音视频宁可丢少量帧也不能等重传导致卡顿和WebSocket业务诉求完全相反。二、断线重连区分【TCP层断连】和【业务层JS重连】重点TCP本身没有自动断线重连机制TCP连接一旦四次挥手、或者长时间探测失败断开TCP内核不会自动重新三次握手建立连接。我们平时看到的WebSocket断线重连是前端JS代码写的业务逻辑不是TCP内核自动完成。当网络断开比如切Wi‑Fi、网线拔掉TCP层发生的事情正常业务收发停止两端尝试发包但是数据包发不出去。TCP开启Keepalive保活探测包定时发很小的探测数据包看对方还能不能应答。如果探测包多次都没有收到ACK回执TCP内核判定这条TCP逻辑通道已经失效。内核直接销毁这条连接释放文件描述符标记连接关闭。注意很多时候网络突然拔线不会走优雅四次挥手属于异常断连RST复位包直接粗暴拆掉连接没有挥手流程。此时前端浏览器的WebSocket对象触发onclose事件通知JS连接断了。JS业务代码启动重连逻辑循环发起新的WebSocket握手底层就是新建TCP连接三次握手然后走HTTP升级协议为WebSocket。新建一套全新TCP四元组旧连接已经彻底作废不是修复原来那条坏掉的TCP通道。两个容易混淆的误区❌ TCP Keepalive ≠ 断线重连Keepalive只是检测连接死没死检测到死掉之后内核只会关掉旧连接不会主动重建。重建连接交给上层应用。❌ 重连是修复旧TCP管道不是修复是废掉旧快递通道重新走一遍三次握手新开一条全新的快递通道。PHP后端视角Swoole/Hyperf服务端TCP也会开启keepalive当客户端网络异常掉线服务端TCP探测超时后Swoole会触发onClose回调。服务端本身不会主动重连客户端只能等待前端发起新一轮握手建立新连接。业务上一般会用用户ID绑定会话重连成功后恢复会话状态。一句话总结WebSocket需要可靠有序的双向消息所以底层选用TCPTCP只管检测连接死亡断线重连是前端业务代码重新发起全新TCP握手。