刚开始接触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封装好后,剩下的就不是问题了