我正在尝试在Angular / Rails应用中设置消息通知。
当用户登录时,我想打开一个SSE连接,该连接将订阅Redis流,并在用户收到新消息时向客户端发送警报。
我的SSE设置正常,但无法找到用户注销时可靠关闭SSE连接的方法。我正在尝试构建一个服务来处理SSE的开启和关闭:
angular.module('messagesApp')
.factory('StreamHandler', function(CookieHandler, MessageStream){
var StreamHandler = {
set: function(){
var user
user = CookieHandler.get();
MessageStream.get = function(){
var source = new EventSource('/api/v1/messages/count?id='+user.id)
return source
}
},
get: function(){
var source = MessageStream.get()
source.onmessage = function(event) {
//do something
}
},
kill: function(){
var source = MessageStream.get()
source.close()
}
}
return StreamHandler
})
我无法弄清楚如何杀死StreamHandler.set()
中打开的流。我在kill
属性中的尝试不起作用,因为调用getter实际上会创建一个新流?
我对其他方法持开放态度:我只需要一种在用户登录/注销时设置和终止EventSource
流的方法。
答案 0 :(得分:2)
问题是我在我的EventSource
属性中放置了创建get
的函数,而不是放置实际的EventSource
对象。一些变化使其有效:
.factory('StreamHandler', function(CookieHandler, MessageStream){
var StreamHandler = {
set: function(){
var user
user = CookieHandler.get();
var source = new EventSource('/api/v1/messages/count?id='+user.id)
MessageStream.get = source
},
get: function(){
var source = MessageStream.get
source.onmessage = function(event) {
console.log(event)
}
source.onerror = function(error) {
source.close()
}
},
kill: function(){
var source = MessageStream.get
source.close();
}
}
return StreamHandler
})
答案 1 :(得分:1)
了解Oboe.js - http://oboejs.com/examples
使用双簧管,我基本上做了(我想你不需要在这种情况下注入$ source和$ http):
.factory('MyStreamingResource', ['$resource', '$http',
function($resource, $http) {
return {
stream: function(options, startFn, nodeFn, doneFn) {
oboe('//url/' + 'maybeSomeOptions/?maybe=' + options.passedAbove)
.start(startFn)
.node(options.path, nodeFn)
.done(doneFn);
}
};
}
]);
然后简单地注入它并从一些控制器调用:
MyStreamingResource.stream({
passedAbove: 'foo',
path: 'items.*'
},
// start callback
function(status, headers){
// console.dir(headers);
// this.abort(); // could be called from here too
},
// node callback (where your data is going to be streamed to)
function(data){
if(data !== null) {
console.dir(data);
//this.abort();
}
},
// done (if you really want to wait)
function(parsedJson){
// ...
});
与您使用$ http看到的其他服务非常相似,但您需要考虑更多回调。
Oboe.js对我来说就像一个魅力和Golang go-json-rest软件包流式传输响应(即使使用无效的JSON - 这在流中非常常见,因为它们还没有完成并赢得了#t有结束标签或将有额外的逗号等)。只需确保脚本的浏览器版本包含在您的页面上,您就可以随时调用它。我花了很长时间搜索如何使用AngularJS进行此操作,但它似乎并不是一个直接的设施。如果可能的话。
当然,从这里你可以弄清楚如何使它适合你的需要...更新$ scope中的东西等。