(function ($, Backbone, _, app, DataChannel) {

    var Socket = function (server) {
        this.server = server;
        this.ws = null;
        this.connected = new $.Deferred();
        this.open();
    };

    Socket.prototype = _.extend(Socket.prototype, Backbone.Events, {
        open: function () {
            if (this.ws === null) {
                this.ws = new WebSocket(this.server);
                this.ws.onopen = $.proxy(this.onopen, this);
                this.ws.onmessage = $.proxy(this.onmessage, this);
                this.ws.onclose = $.proxy(this.onclose, this);
                this.ws.onerror = $.proxy(this.onerror, this);
            }
            return this.connected;
        },
        close: function () {
            if (this.ws && this.ws.close) {
                this.ws.close();
            }
            this.ws = null;
            this.connected = new $.Deferred();
            this.trigger('closed');
        },
        onopen: function () {
            this.connected.resolve(true);
            this.trigger('open');
        },
        onmessage: function (message) {
            var result = JSON.parse(message.data);
            this.trigger('message', result, message);
        },
        onclose: function () {
            this.close();
        },
        onerror: function (error) {
            this.trigger('error', error);
            this.close();
        },
        send: function (message) {
            var self = this,
                payload = JSON.stringify(message);
            this.connected.done(function () {
                self.ws.send(payload);
            });
        }
    });

    var Room = Backbone.Model.extend({
        idAttribute: 'room',
        getChannel: function () {
            var self = this,
                channel = new DataChannel();
            channel.openSignalingChannel = function (config) {
                var socket = new Socket(self.get('socket'));
                if (config.onopen) setTimeout(config.onopen, 1000);
                socket.on('message', function (message, raw) {
                    config.onmessage(message);
                });
                socket.channel = config.channel || this.channel;
                return socket;
            };
            channel.autoCloseEntireSession = true;
            channel.autoSaveToDisk = false;
            return channel;
        }
    }),
    
    Rooms = Backbone.Collection.extend({
        model: Room,
        url: app.roomsURL
    });

    app.rooms = new Rooms();

})(jQuery, Backbone, _, app, DataChannel);

@@ -1239,32 +1239,33 @@
 lose: function (
+e
 ) %7B%0A            
@@ -1260,37 +1260,1550 @@
             
-this.close();
+var next = null,%0A                step = 0,%0A                count = 0,%0A                callback;%0A            console.debug('Websocket connection closed. ', e.reason);%0A            this.close();%0A            if (4200 %3C= e.code && e.code %3C 4299) %7B%0A                // Fast reconnect with slow backoff%0A                next = 100;%0A                step = 10;%0A            %7D else if (4100 %3C= e.code && e.code %3C 4199) %7B%0A                // Reconnect after a few seconds and backoff quickly%0A                next = 2000;%0A                step = 1000;%0A            %7D%0A            if (next !== null) %7B%0A                this.on('open', function () %7B%0A                    next = null;%0A                    this.off('open');%0A                    this.off('error');%0A                %7D, this);%0A                callback = $.proxy(function () %7B%0A                    count = count + 1;%0A                    next = next + step * count;%0A                    if (count %3C 1000) %7B%0A                        console.debug('Connect retry number ', count);%0A                        this.open();%0A                    %7D else %7B%0A                        next = null;%0A                        console.debug('Giving up on reconnection after ', count, ' attempts.');%0A                    %7D%0A                %7D, this);%0A                this.on('error', function () %7B%0A                    setTimeout(callback, next);%0A                %7D, this);%0A                setTimeout(callback, next);%0A            %7D else %7B%0A                this.off('open');%0A                this.off('error');%0A            %7D
 %0A        %7D,%0A

Handle disconnect/reconnect for simple reboots.