AngularJS 1.x Socket.IO工厂注入:事件收发及连接检查问题
解决AngularJS Socket工厂未检查连接状态导致的异常问题
我明白你遇到的痛点——直接调用socket.emit时,如果Socket.IO连接还没建立或者已经断开,肯定会抛出异常,搞崩应用的稳定性。咱们可以通过改造现有的socket工厂,添加连接状态跟踪和安全发送逻辑来彻底解决这个问题。
改造后的Socket工厂
我们在工厂里维护连接状态,监听Socket.IO的连接/断开事件更新状态,同时在emit方法里先做连接检查,甚至可以缓存未发送的事件,等连接恢复后自动补发:
angularApp.factory('socket', function ($rootScope) { var socket = io(); var isConnected = false; // 缓存未发送的事件,连接恢复后自动发送 var pendingEvents = []; // 监听连接建立事件 socket.on('connect', function() { isConnected = true; $rootScope.$apply(); // 连接恢复后批量发送缓存的事件 pendingEvents.forEach(function(event) { socket.emit(event.eventName, event.data, event.callback); }); pendingEvents = []; }); // 监听连接断开事件 socket.on('disconnect', function() { isConnected = false; $rootScope.$apply(); }); return { // 暴露连接状态给控制器调用 isConnected: function() { return isConnected; }, on: function (eventName, callback) { socket.on(eventName, function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); }, emit: function (eventName, data, callback) { if (isConnected) { socket.emit(eventName, data, function () { var args = arguments; $rootScope.$apply(function () { if (callback) { callback.apply(socket, args); } }); }); } else { // 未连接时缓存事件 pendingEvents.push({ eventName: eventName, data: data, callback: callback }); // 可选:通过回调通知调用者当前未连接 if (callback) { $rootScope.$apply(function() { callback(new Error('Socket未连接,请求已加入缓存')); }); } } } }; });
控制器中的使用方式
现在你可以放心调用emit,工厂会自动处理连接状态;如果需要给用户做即时提示,也可以手动检查连接状态:
$scope.$on('beginDataTransfer', function() { if (socket.isConnected()) { socket.emit('dataTransfer', "SOME DATA", function(err) { if (err) { console.error('数据发送失败:', err); // 这里可以给用户显示错误提示 } }); } else { console.log('Socket未连接,请求已缓存,将在连接恢复后发送'); // 也可以在这里给用户弹出提示框 } });
关键改进点
- 实时连接状态跟踪:通过监听Socket.IO的
connect/disconnect事件,精准同步连接状态到Angular作用域 - 事件缓存补发:避免未连接时丢失请求,连接恢复后自动补发缓存的事件
- 友好的错误回调:给调用者提供错误反馈,方便做前端提示或异常处理
- Angular作用域同步:所有状态变化都通过
$rootScope.$apply()同步到Angular消化周期,确保视图能及时响应连接状态变化
这样改造后,再也不用担心因为Socket未连接触发异常了,还能提升应用的健壮性和用户体验。
内容的提问来源于stack exchange,提问作者Beni
相关产品推荐
相关产品推荐

