Проблемы при хранении объектов обработки соединений WebSocket с помощью jQuery.data () - что лучше всего сделать? - PullRequest
5 голосов
/ 14 августа 2011

У меня есть асинхронный работник очереди, работающий как скрипт Tornado на моем сервере - он содержит подкласс PeriodicTask Tornado, который принимает события от Redis. Чтобы отслеживать очередь, я настроил подкласс tornado.websocket.WebSocketHandler для URL, а затем инкапсулировал клиентский JavaScript WebSocket в плагин 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 и сообщение о том, что объект сокета больше недействителен.

enter image description here

Как только страница переходит в это состояние ошибки, мне нужно перезапустить браузер и серверный сценарий websocket, чтобы все снова запустилось.

... Есть ли лучший способ настроить вещи, чем у меня (с window.setInterval() и прочее)?

1 Ответ

1 голос
/ 11 сентября 2011

Что ж, вероятно, не самая лучшая идея - прикреплять тяжелый объект к DOM.

В качестве альтернативы вы можете иметь глобальное хранилище (возможно, словарь) с отображением ключей на сокеты и хранить ключ только какАтрибут obj DOM

...