AngularJS中$websocket是轻量WebSocket封装,需显式声明ngWebSocket依赖;Angular 2+无此服务,须手写封装并处理生命周期、重连及RxJS集成。

Angular 1.x(即 AngularJS)项目里,$websocket 是最直接、最轻量的 WebSocket 封装方式;但如果你用的是 Angular 2+(TypeScript),原生不带 $websocket,必须自己封装或借助 sockjs-client 等第三方库——混淆这两者是绝大多数人踩坑的第一步。
AngularJS 项目中正确注入和使用 $websocket
核心前提是:模块依赖必须显式声明 ngWebSocket,且仅限 AngularJS 1.x 兼容。
- 安装后,在模块定义时漏掉依赖会导致
$websocket is not defined错误:angular.module('myApp', ['ngWebSocket']) -
$websocket是一个工厂函数,不是服务实例,调用它才会生成连接:var ws = $websocket('wss://api.example.com/ws'),不能直接当服务注入 - 消息回调中若更新
$scope数据,需手动触发 digest(除非启用autoApply: true):ws.onMessage(function(event) { $scope.$apply(() => { $scope.data = JSON.parse(event.data); }); }) - 别在控制器里反复调用
$websocket(...)创建新连接——每个调用都新建 socket,容易耗尽客户端连接数
Angular 2+ 中封装 WebSocket 服务的最小可行写法
TypeScript 项目没有 $websocket,必须手写服务类,且要处理连接生命周期与 RxJS 订阅管理。
- 不要直接 new WebSocket() 后裸露在组件中——状态不可控、无法统一错误重试、难以测试
- 推荐用
Subject暴露消息流:getMessages(): Observable,让组件只订阅,不碰 socket 实例 - 务必监听
onclose并判断event.code !== 1000,非正常关闭才触发重连逻辑,否则会陷入无限断连-重连循环 - 发送前必须检查
socket.readyState === WebSocket.OPEN,否则报错且消息丢失;可加一层safeSend()封装
$websocket 的 send() 方法参数陷阱
send() 看似简单,但传参类型直接影响底层序列化行为和服务器接收结果。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 传入对象(如
{type: 'ping', ts: Date.now()})时,$websocket会自动JSON.stringify(),服务器收到的是字符串,不是原始对象 - 传入已序列化的字符串(如
JSON.stringify(...)再传给send()),会被二次序列化,变成"{\"type\":\"ping\"}"—— 服务器解析失败 - 如果后端要求二进制帧(如
ArrayBuffer),$websocket不支持,必须降级用原生WebSocket实例 -
send()返回 Promise,但默认不 reject 失败(比如连接未就绪时发消息),需自行包装校验逻辑
重连机制不是开箱即用,必须显式配置
无论是 angular-websocket 还是手写服务,**默认都不自动重连**。所谓“内置重连”只是库提供了配置入口,不填等于关闭。
- AngularJS 版需在构造时传第三个参数:
$websocket(url, null, { reconnectIfNotNormalClose: true, reconnectInterval: 2000 }) - Angular 2+ 手写服务中,
onclose回调里不能直接this.connect(),否则可能并发多个连接;应加锁标志位或用setTimeout+ 状态检查 - 重连间隔建议用指数退避(如 1s → 2s → 4s),避免瞬间打爆服务器;
maxReconnectAttempts必须设上限,否则用户关机再开机,前台还在狂试连 - 别忽略
onerror:网络抖动、证书过期、CORS 拒绝都会进这里,但不会触发onclose,得单独处理
真实项目里,WebSocket 不是“连上就行”,而是要扛住页面刷新、标签页休眠、弱网切换、服务端滚动升级——这些场景下连接状态、消息顺序、重复投递的处理逻辑,比初始化代码多十倍。别省略心跳保活、消息 ID 去重、离线缓存队列这些细节,它们不出问题时看不见,一出就是线上事故。










