websocket 并不总是在 angularjs 应用程序中触发 onopen 函数
websocket not always firing onopen function in angularjs app
我有一个应用程序从外部设备读取一些值。我正在使用 angularjs 作为我的 javascript 框架。我正在使用 angular-ui 进行路由。
我正在使用 resolve 将网络套接字传递给控制器,因为它可以在多个屏幕中使用
.state('dashboard.count', {
parent: 'dashboard',
url: "/lane/:laneID",
templateUrl: '/app/count/count.html',
controller: 'CountCtrl as vm',
resolve: {
websocket: ['webSocketFactory', function (webSocketFactory) {
return webSocketFactory.websocket;
}]
}
});
websocket 被工厂检索:
function webSocketFactory($log, wsUri) {
var factory = {
sendMessage: sendMessage,
websocket: new WebSocket('myurl')
}
return factory;
}
}
在我的控制器中,我对 websocket 进行了简单的调用 API
websocket.onopen = function () {
$log.debug('open');
webSocketFactory.sendMessage('send my message through the factory');
vm.connecting = false;
}
可能有 70% 的时间它工作正常 vm.connecting
设置为 false,我可以使用网络套接字。然而,这是不可预测的。
我对这个 SO Question 上接受的答案不是很满意,投票更高的似乎是我正在遵循的模式。有没有人有任何建议如何使它更可预测?
我怀疑它不可靠,因为 onopen
回调会在您的控制器实例准备就绪之前发生。如果我是对的,下面的代码应该可以工作,并且还允许您排队等待 websocket 连接后立即发送的消息。
尝试在创建 new WebSocket()
后立即添加一个 onopen
函数,并获得处理套接字而不是控制器的所有内部工作的服务。
function webSocketService($rootScope, $log, $q, wsUri) {
var websocketConnectedDeferred, isConnected, websocket;
var createNewWebSocket = function(url){
websocketConnectedDeferred = $q.defer();
isConnected = false;
websocket = new WebSocket(url)
websocket.onopen = onWebSocketOpen;
websocket.onmessage = onWebSocketMessage;
return websocket;
};
var onWebSocketOpen = function(){
$log.debug('open');
isConnected = true;
websocketConnectedDeferred.resolve();
};
var onWebSocketMessage = function(incomingMessage){
$rootScope.$broadcast('websocketMessageReceived', incomingMessage);
};
var sendMessage = function(message){
websocketConnectedDeferred.promise.then(function(){
websocket.doTheThing(message);
});
};
var iswebsocketConnectedDeferred = function(){
return isConnected;
};
var service = {
sendMessage: sendMessage,
websocket: createNewWebSocket('myUrl'),
iswebsocketConnectedDeferred: iswebsocketConnectedDeferred
};
return service;
}
控制器:
$scope.$on('websocketMessageReceived', function(event, incomingMessage){
// Do something with 'incomingMessage'
});
webSocketService.sendMessage('send my message through the factory');
我有一个应用程序从外部设备读取一些值。我正在使用 angularjs 作为我的 javascript 框架。我正在使用 angular-ui 进行路由。
我正在使用 resolve 将网络套接字传递给控制器,因为它可以在多个屏幕中使用
.state('dashboard.count', {
parent: 'dashboard',
url: "/lane/:laneID",
templateUrl: '/app/count/count.html',
controller: 'CountCtrl as vm',
resolve: {
websocket: ['webSocketFactory', function (webSocketFactory) {
return webSocketFactory.websocket;
}]
}
});
websocket 被工厂检索:
function webSocketFactory($log, wsUri) {
var factory = {
sendMessage: sendMessage,
websocket: new WebSocket('myurl')
}
return factory;
}
}
在我的控制器中,我对 websocket 进行了简单的调用 API
websocket.onopen = function () {
$log.debug('open');
webSocketFactory.sendMessage('send my message through the factory');
vm.connecting = false;
}
可能有 70% 的时间它工作正常 vm.connecting
设置为 false,我可以使用网络套接字。然而,这是不可预测的。
我对这个 SO Question 上接受的答案不是很满意,投票更高的似乎是我正在遵循的模式。有没有人有任何建议如何使它更可预测?
我怀疑它不可靠,因为 onopen
回调会在您的控制器实例准备就绪之前发生。如果我是对的,下面的代码应该可以工作,并且还允许您排队等待 websocket 连接后立即发送的消息。
尝试在创建 new WebSocket()
后立即添加一个 onopen
函数,并获得处理套接字而不是控制器的所有内部工作的服务。
function webSocketService($rootScope, $log, $q, wsUri) {
var websocketConnectedDeferred, isConnected, websocket;
var createNewWebSocket = function(url){
websocketConnectedDeferred = $q.defer();
isConnected = false;
websocket = new WebSocket(url)
websocket.onopen = onWebSocketOpen;
websocket.onmessage = onWebSocketMessage;
return websocket;
};
var onWebSocketOpen = function(){
$log.debug('open');
isConnected = true;
websocketConnectedDeferred.resolve();
};
var onWebSocketMessage = function(incomingMessage){
$rootScope.$broadcast('websocketMessageReceived', incomingMessage);
};
var sendMessage = function(message){
websocketConnectedDeferred.promise.then(function(){
websocket.doTheThing(message);
});
};
var iswebsocketConnectedDeferred = function(){
return isConnected;
};
var service = {
sendMessage: sendMessage,
websocket: createNewWebSocket('myUrl'),
iswebsocketConnectedDeferred: iswebsocketConnectedDeferred
};
return service;
}
控制器:
$scope.$on('websocketMessageReceived', function(event, incomingMessage){
// Do something with 'incomingMessage'
});
webSocketService.sendMessage('send my message through the factory');