You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS 1.4.4报$rootScope未定义,求SockJS接收Stomp事件解决方案

解决AngularJS 1.4.4中$rootScope未定义错误并实现Stomp over SockJS事件接收

一、修复Uncaught ReferenceError: $rootScope is not defined错误

这个报错的核心原因是AngularJS 1.x的依赖注入系统无法自动识别类构造函数中的参数,1.4版本对类语法的控制器支持有限,必须显式声明依赖项才能让Angular正确注入服务。你需要做这两步:

  1. 给控制器添加显式依赖注入声明
    在WebSocketController.js的类定义外部,添加$inject属性,明确告诉Angular要注入的服务:
class WebSocketController {
 constructor($rootScope, $scope) {
 Object.assign(this, {$rootScope, $scope});
 this.onConnected = this.onConnected.bind(this);
 this.stompClient = null;
 let vm = this;
 setTimeout(function () {
 vm.connect();
 }, 2000);
 }

 // 后续方法...
}

// 关键:必须显式声明依赖,Angular才能正确注入
WebSocketController.$inject = ['$rootScope', '$scope'];
  1. 确认控制器注册的模块正确性
    检查app.js中控制器的注册代码,确保是在你实际的应用模块下注册:
// 替换成你的应用模块名,比如"myApp"
var myApp = angular.module('myApp', []);
myApp.controller('webSocketController', WebSocketController);

如果模块名称不匹配,控制器无法被Angular初始化,也会导致依赖注入失败。

二、完整实现Stomp over SockJS接收服务器事件

接下来完善控制器代码,实现连接、订阅、接收事件的完整逻辑:

1. 先引入必要的脚本

在你的HTML页面中按顺序引入SockJS和Stomp.js:

<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/lib/stomp.min.js"></script>

2. 完整的WebSocketController代码

class WebSocketController {
 constructor($rootScope, $scope) {
 Object.assign(this, {$rootScope, $scope});
 this.onConnected = this.onConnected.bind(this);
 this.onMessageReceived = this.onMessageReceived.bind(this);
 this.stompClient = null;
 let vm = this;
 // 延迟连接,确保Angular和页面初始化完成
 setTimeout(function () {
 vm.connect();
 }, 2000);
 }

 // 连接SockJS服务器
 connect() {
 // 替换成你的服务器WebSocket端点地址
 var socket = new SockJS('/your-websocket-endpoint');
 this.stompClient = Stomp.over(socket);
 
 // 开发阶段可以保留debug日志,生产环境建议关闭
 this.stompClient.debug = null;

 // 连接服务器,若需要认证可在第一个参数传入凭证
 this.stompClient.connect({}, this.onConnected, function(error) {
 console.error('WebSocket连接失败:', error);
 // 连接失败自动重试
 setTimeout(() => this.connect(), 5000);
 }.bind(this));
 }

 // 连接成功后的回调:订阅事件主题
 onConnected(frame) {
 console.log('WebSocket连接成功:', frame);
 // 替换成你的服务器实际发布事件的主题路径
 this.stompClient.subscribe('/topic/all-events', this.onMessageReceived);
 }

 // 接收服务器事件的回调
 onMessageReceived(message) {
 console.log('收到服务器事件:', message);
 // 解析JSON格式的消息体(根据服务器实际格式调整)
 var eventData = JSON.parse(message.body);
 // 方式1:通过$rootScope广播事件,让其他控制器监听
 this.$rootScope.$broadcast('websocket-event', eventData);
 // 方式2:直接更新当前控制器的视图数据
 this.$scope.receivedEvent = eventData;
 // 手动触发Angular消化周期,因为Stomp回调在外部执行
 this.$scope.$apply();
 }

 // 页面销毁时断开连接,避免内存泄漏
 $onDestroy() {
 if (this.stompClient && this.stompClient.connected) {
 this.stompClient.disconnect();
 console.log('已断开WebSocket连接');
 }
 }
}

// 再次强调:显式声明依赖注入
WebSocketController.$inject = ['$rootScope', '$scope'];

3. 关键细节说明

  • 手动调用$apply():Stomp的消息回调运行在Angular的消化周期之外,必须调用$scope.$apply()才能让视图更新。
  • 重连机制:添加了连接失败后的自动重试逻辑,提升稳定性。
  • 资源清理:实现$onDestroy钩子,在控制器销毁时断开连接,避免无效连接占用资源。
  • 主题订阅:/topic/all-events是示例主题,需要替换成你的服务器实际发布事件的路径。

三、在视图中关联控制器

确保你的HTML视图正确绑定控制器:

<div ng-controller="webSocketController">
 <h3>最新收到的事件:</h3>
 <pre>{{ receivedEvent | json }}</pre>
</div>

内容的提问来源于stack exchange,提问作者Dharita Chokshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:25:37