AngularJs 里如何监听socket

刚开始接触angularJS不太熟悉,我想做一个即时通讯的页面,想法是建立链接后,在onmessage里监听消息,有新消息的时候,能够在controller里有提示。代码如下,ws.onMessage(function(event) {
$rootScope.$apply(function(){
var message;
try {
message = JSON.parse(event.data);
} catch(e) {
console.info(e);
}
messages.push({
to : message.to,
from : message.from,
context : message.message,
sessionid : message.sessionId
});
});
});



```chatApp.controller("userListCtrl", ['$scope', '$http', 'msgService', function($rootScope, $scope, $http, msgService) {
    //加载聊天用户列表
    $rootScope.$on("messageListener", function(event, msgService) {
        console.info("chage")

    })

    如上,第一次做angularJS,不太清楚,这个问题已经困扰我好几天了,网上资料也很少,就想有个人指点一下。

具体例子代码详见https://github.com/vtortola/WebSocketListener/tree/master/samples/TerminalServer
这里给你提供了一个使用Angular 把WebSocket封装成一个service的思路,具体怎么改还得根据你现有的代码

可以声明一个AngularJS的service,然后这样调用它

监听

    $connection.listen(function (msg) { return msg.type == "CreatedTerminalEvent"; }, 
        function (msg) {
            addTerminal(msg);
            $scope.$$phase || $scope.$apply();
   });

一次性监听

 $connection.listenOnce(function (data) {
        return data.correlationId && data.correlationId == crrId;
    }).then(function (data) {
        $rootScope.addAlert({ msg: "Console " + data.terminalType + " created", type: "success" });
    });

发送

 $connection.send({
        type: "TerminalInputRequest",
        input: cmd,
        terminalId: $scope.terminalId,
        correlationId: $connection.nextCorrelationId()
    });

service的代码

angular.module("terminalServer", ['ui.bootstrap','vtortola.ng-terminal'])
 .service('$connection', ["$q", "$timeout", "websocketUrl", "$rootScope", function ($q, $timeout, websocketUrl, $rootScope) {

    var connection = function () {



        var me = {};

        var listeners = [];

        var oneListeners = [];



        me.isConnected = false;



        oneListeners.removeOne = function (listener) {

            var index = oneListeners.indexOf(listener);

            if(index!=-1)

                oneListeners.splice(index, 1);

        };



        var correlationId = 1;

        me.nextCorrelationId = function () {

            return correlationId++;

        };



        $rootScope.queuedMessages = [];



        me.listen = function (predicate, handler) {

            listeners.push({ p: predicate, h: handler });

        };



        me.listenOnce = function (predicate, timeout) {

            var deferred = $q.defer();

            deferred.done = false;

            var listener = { d: deferred, p: predicate };

            oneListeners.push(listener);

            if (timeout) {

                $timeout(function () {

                    if (!deferred.done)

                        deferred.reject('timeout');

                    oneListeners.removeOne(listener);

                }, timeout);

            }

            var promise = deferred.promise;

            promise.then(function (data) {

                deferred.done = true;

            });

            return promise;

        };



        var onopen = function () {

            $rootScope.websocketAvailable = true;

            me.isConnected = true;

            $rootScope.$$phase || $rootScope.$apply();

            if ($rootScope.queuedMessages) {

                for (var i = 0; i < $rootScope.queuedMessages.length; i++) {

                    ws.send(JSON.stringify($rootScope.queuedMessages[i]));

                }

                $rootScope.queuedMessages = null;

                $rootScope.$$phase || $rootScope.$apply();

            }

        };



        var onclose = function () {

            me.isConnected = false;

            $rootScope.websocketAvailable = false;

            $rootScope.$$phase || $rootScope.$apply();

            $rootScope.queuedMessages = $rootScope.queuedMessages || [];



            setTimeout(function () {

                ws = connect();

            }, 5000);

        };



        var onmessage = function (msg) {

            var obj = JSON.parse(msg.data);

            for (var i = 0; i < listeners.length; i++) {

                var listener = listeners[i];

                if (listener.p(obj))

                    listener.h(obj);

            }

            var remove = [];

            for (var i = 0; i < oneListeners.length; i++) {

                var listener = oneListeners[i];

                if (listener.p(obj)) {

                    var o = obj;

                    listener.d.resolve(o);

                    remove.push(listener);

                }

            }

            for (var i = 0; i < remove.length; i++) {

                oneListeners.removeOne(remove[i]);

            }

        };



        var onerror = function () {

            console.log('onerror');

        };



        me.send = function (obj) {



            if ($rootScope.queuedMessages)

                $rootScope.queuedMessages.push(obj);

            else

                ws.send(JSON.stringify(obj));

        }



        var setHandlers = function (w) {

            w.onopen = onopen;

            w.onclose = onclose;

            w.onmessage = onmessage;

            w.onerror = onerror;

        };



        var connect = function () {

            console.log('connecting...');

            var w = new WebSocket(websocketUrl);

            setHandlers(w);

            return w;

        }



        var ws = connect();



        return me;

    };

    return connection();

}])

因为service是可以在所有controller里面使用的,所以service封装好后,剩下的就不是问题了