websocket连接失败主因是服务端未启动、协议不匹配(如https页用ws非wss)或跨域未处理;发消息前须检查readystate为open;广播时需过滤发送者;消息需清洗再序列化;二进制数据慎用websocket传输。

WebSocket 连接建立失败的常见原因
客户端 new WebSocket() 报错 WebSocket connection to 'ws://...' failed,大概率不是代码写错了,而是服务端没跑、协议不匹配或跨域未处理。
- 确认服务端已启动且监听的是
ws://(开发环境)或wss://(生产),HTTP 服务不能直接升级为 WebSocket - 浏览器访问
http://页面时,ws://是允许的;但如果是https://页面,必须用wss://,否则被浏览器拦截 - Node.js 后端用
ws库时,别忘了把 WebSocket 服务器挂到 HTTP 服务上(例如wsServer = new WebSocket.Server({ server: httpServer })),否则无法共享端口和完成握手
前端发送消息前必须检查 readyState
websocket.readyState 不是永远为 1,网络抖动、重连中、刚初始化时都可能是 0(CONNECTING)或 2(CLOSING)甚至 0(CLOSED),直接 send() 会抛 InvalidStateError。
一套面向小企业用户的企业网站程序!功能简单,操作简单。实现了小企业网站的很多实用的功能,如文章新闻模块、图片展示、产品列表以及小型的下载功能,还同时增加了邮件订阅等相应模块。公告,友情链接等这些通用功能本程序也同样都集成了!同时本程序引入了模块功能,只要在系统默认模板上创建模块,可以在任何一个语言环境(或任意风格)的适当位置进行使用!
- 发消息前加一层判断:
if (ws.readyState === WebSocket.OPEN) { ws.send(msg); } - 更稳妥的做法是加个队列:状态未就绪时暂存消息,监听
open事件后批量发送 - 别依赖
onopen回调里立刻发消息——它触发时连接虽建立,但底层 TCP 握手可能刚完成,极短时间窗口内readyState仍可能未稳定为OPEN
服务端广播消息时要过滤发送者
用 ws 库实现群聊时,如果对所有连接调用 client.send(),发送者自己也会收到自己发的消息,导致 UI 重复渲染、输入框清空后又闪现一次。
- 遍历
wsServer.clients时,用client !== sender排除源头连接 - 注意
clients是一个Set,不是数组,不能用forEach索引判断,得用引用比较 - 如果需要私聊,建议在消息体里带
to字段,服务端按client.id或自定义标识匹配目标连接,而不是靠广播+前端过滤
消息序列化别直接 JSON.stringify() 原始对象
用户输入可能含控制字符、超长文本、循环引用对象,直接 JSON.stringify() 后 ws.send() 容易触发异常或被中间代理截断。
- 发送前做最小化清洗:
JSON.stringify({ type: 'message', content: String(input).trim().slice(0, 2000) }) - 服务端收到后也应先
try...catch解析,解析失败直接close(4001, 'invalid json'),避免后续逻辑崩溃 - 二进制数据(如小图 base64)慎用 WebSocket 传输——不是不支持,而是容易撑爆内存或触发代理限流;大文件走单独 HTTP 接口更稳
Upgrade 头透传、心跳保活间隔这些点,比写业务逻辑更容易卡住。









