我有一个SignalR的实现,它被用作聊天客户端。问题似乎是我有一个客户端计时器,即ping服务器以通知所有其他客户端用户的状态。
在这种情况下,我有一个心跳和最新的活动。心跳每十五秒左右就会到达服务器,而最新活动会跟踪用户的交互性。将这两个值传递给服务器,以便可以通知所有其他客户端其他人的状态。即:如果用户A没有移动他们的鼠标超过一分钟,当他们的心跳到达服务器时,它将通过SignalR向其他所有用户广播他们现在“离开”..
无论如何,我有一个问题,即SignalR连接似乎呈指数级增长,连接到聊天应用程序的用户数量就越大。
这是客户端js计时器的来源,我怀疑它很可疑,但我不确定为什么:
define(['jquery', 'underscore', 'backbone'],
function ($, _, Backbone) {
var Timer = Backbone.Model.extend({
defaults: {
interval: 1 * 10 * 1000,
timeout: null
},
initialize: function (options) {
_.bindAll(this, 'start', 'tick', 'stop', 'tickNow');
if (options.interval) {
this.set('interval', options.interval);
}
},
start: function () {
var timer = setTimeout(this.tick, this.get('interval'));
this.set('timeout', timer);
},
tick: function () {
var self = this;
self.trigger('timerexpired', this);
self.start();
},
tickNow: function () {
var self = this;
self.stop();
self.trigger('timerexpired', this);
self.start();
},
stop: function () {
clearTimeout(this.get('timeout'));
}
});
return Timer;
});
答案 0 :(得分:2)
我注意到您在启动计时器方法中使用了this
关键字。可能是您对this.tick
调用的调用在实际触发时脱离了上下文。尝试:
start: function () {
var self = this;
var timer = setTimeout(this.tick, self.get('interval'));
this.set('timeout', timer);
},
在浏览器中,将一个断点放入tick
方法并检查您确实引用了正确的计时器。
答案 1 :(得分:1)
我没有看到进展如何必然是指数级的,但线性进展肯定会倾向于它。基本上,你可以在这里做两件事:
答案 2 :(得分:0)
您不应该只将this.tick
作为第一个参数传递给setTimeout
,因为tick
方法执行时this
将绑定到全局window
对象而不是Timer
实例。
您还应该确保在start
实例已经运行时不要调用Timer
。我会改变以下方法:
start: function () {
var self = this;
if (this.get('timeout') !== null) {
throw "start must not be called when the Timer is already running";
}
// creating a closure ensures this is bound correctly in tick()
var timer = setTimeout(function () {
self.tick();
}, this.get('interval'));
this.set('timeout', timer);
},
tick: function () {
this.set('timeout', null);
this.trigger('timerexpired', this);
this.start();
},
stop: function () {
clearTimeout(this.get('timeout'));
this.set('timeout', null);
}
检查Timer是否正常工作的明显方法是将对console.log的调用绑定到timerexpired事件,以确保事件的触发时间不超过预期。
如果您需要帮助确定并发连接数量失控的原因,您应该将代码发布到停止和启动SignalR连接的位置。