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正确注入服务。你需要做这两步:
- 给控制器添加显式依赖注入声明
在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'];
- 确认控制器注册的模块正确性
检查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
相关产品推荐
相关产品推荐

