使用 jQuery.data() 存储 WebSocket 连接句柄对象时出现问题 - 最好的做法是什么?
我有一个异步队列工作线程作为 Tornado 脚本在我的服务器上运行——它托管 Tornado 的 periodictask 的子类,它消耗来自 Redis 的事件。为了监视队列,我在 URL 上设置了一个 tornado.websocket.WebSocketHandler
子类,然后将客户端 WebSocket JavaScript 封装在 jQuery 插件中 (这里是完整的代码)。
这个想法是,您可以在服务器上拥有多个队列,因此您可以使用 jQuery 模块来设置一个专门监视该队列的小部件。目前,逻辑非常简单——小部件仅指示有多少任务在其目标队列中排队。
下面是相关的初始化代码:
/* init: */ function (_options) {
options = $.extend(options, _options);
var self = this;
self.data('recently', [0,0,0,0,0,0,0,0,0]);
self.data('options', options);
self.data('sock', null);
var sock = null;
if ('endpoint' in options && options['endpoint']) {
sock = new WebSocket(options['endpoint']);
sock.onopen = function () {};
sock.onclose = function () {};
sock.onmessage = function (e) {
var d = $.parseJSON(e.data);
if (options.queuename in d) {
var qlen = d[options.queuename]
lastvalues = self.data('recently');
lastvalues.shift();
lastvalues.push(qlen);
if (lastvalues.every(function (itm) { return itm == 0; })) {
self.each(function () {
var elem = $(this);
elem.html("<b>Currently Idle</b>");
});
} else {
self.each(function () {
var elem = $(this);
elem.html("<b>" + qlen + "</b> Queued Signals");
});
}
self.data('recently', lastvalues);
}
}
}
self.data('sock', sock);
return self.each(function () {
var elem = $(this);
elem.data('sock', sock);
});
}
JavaScript 使用 window.setInterval()
定期向套接字发送消息;服务器回复其所请求的队列状态,并且套接字的前端回调更新 DOM。
但问题是:经过几分钟的这种轮询——特别是通过在包含客户端套接字代码的页面之间导航来启动——,套接字会通过抛出异常并显示类似的消息而失败。 >DOM_ERROR_11
以及套接字对象不再有效的消息。
一旦页面进入此错误状态,我必须重新启动浏览器和 服务器 websocket 脚本让一切重新启动。
...有没有比我更好的设置方法(使用 window.setInterval()
等)?
I have an asynchronous queue worker running as a Tornado script on my server -- it hosts a subclass of Tornado's PeriodicTask, which consumes events from Redis. To monitor the queue, I set up a tornado.websocket.WebSocketHandler
subclass on a URL, and then encapsulated the client WebSocket JavaScript in a jQuery plugin (here is the full code).
The idea is, you can have a number of queues on the server, and so you can use the jQuery module to set up a widget that specifically monitors that queue. At the moment, the logic is dead simple -- the widgets merely indicate how many tasks are enqueued in their target queue.
Here's the init code in question:
/* init: */ function (_options) {
options = $.extend(options, _options);
var self = this;
self.data('recently', [0,0,0,0,0,0,0,0,0]);
self.data('options', options);
self.data('sock', null);
var sock = null;
if ('endpoint' in options && options['endpoint']) {
sock = new WebSocket(options['endpoint']);
sock.onopen = function () {};
sock.onclose = function () {};
sock.onmessage = function (e) {
var d = $.parseJSON(e.data);
if (options.queuename in d) {
var qlen = d[options.queuename]
lastvalues = self.data('recently');
lastvalues.shift();
lastvalues.push(qlen);
if (lastvalues.every(function (itm) { return itm == 0; })) {
self.each(function () {
var elem = $(this);
elem.html("<b>Currently Idle</b>");
});
} else {
self.each(function () {
var elem = $(this);
elem.html("<b>" + qlen + "</b> Queued Signals");
});
}
self.data('recently', lastvalues);
}
}
}
self.data('sock', sock);
return self.each(function () {
var elem = $(this);
elem.data('sock', sock);
});
}
The javascript uses window.setInterval()
to periodically send a message to the socket; the server replies with the status of the queue for which it was asked, and the socket's frontend callback updates the DOM.
But the problem is: after a few minutes of this sort of polling -- set off specifically by navigating between pages containing the client socket code -- the sockets fail by throwing an exception with a message like DOM_ERROR_11
and a message that the socket object is no longer valid.
Once the page enters this error condition, I have to restart both the browser and the server websocket script to get everything to start up again.
... Is there a better way to set things up than I have (with the window.setInterval()
and whatnot)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,将重对象附加到 DOM 可能不是最好的主意
您也可以使用全局存储(可能是字典),其中包含套接字映射的键,并且仅将键存储为 DOM obj 属性
Well, it's probably not the best idea to keep a heavy object attached to DOM
You could alternatively have a global storage (probably a dictionary) with keys to sockets mapping, and only store the key as a DOM obj attribute