websocket并不总是在angularjs app中触发onopen功能

时间:2015-04-09 16:36:16

标签: angularjs websocket

我有一个应用程序从外部设备读取一些值。我正在使用angularjs作为我的javascript框架。我正在使用angular-ui进行路由。

我正在使用解决方案将Web套接字传递给控制器​​,因为它可以在多个屏幕中使用

.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上接受的答案并不满意,选票高的似乎是我所遵循的模式。有没有人有任何建议如何使这更可预测?

1 个答案:

答案 0 :(得分:4)

我怀疑它不可靠,因为onopen回调会在控制器实例准备好之前发生。如果我对此有所了解,则以下代码应该可以使用,并且还允许您在websocket连接后立即将消息排队。

尝试在创建onopen后立即添加new WebSocket()函数,并获取服务来处理套接字的所有内部工作,而不是控制器。

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');