lila/public/javascripts/socket.js

106 lines
3.2 KiB
JavaScript

$.websocket = function(url, version, settings) {
this.settings = {
open: function(){},
close: function(){},
message: function(m){},
events: {},
params: {
uid: Math.random().toString(36).substring(5)
},
options: {
name: "unnamed",
debug: true,
offlineDelay: 5000,
offlineTag: false,
pingData: JSON.stringify({t: "p"}),
pingTimeout: 5000,
pingDelay: 2500
}
};
$.extend(true, this.settings, settings);
this.url = url;
this.version = version;
this.options = this.settings.options;
this.ws = null;
this.fullUrl = null;
this.offlineTimeout = null;
this.pingTimeout = null;
this.connect();
$(window).unload(this._destroy);
}
$.websocket.available = window.WebSocket || window.MozWebSocket;
$.websocket.prototype = {
connect: function() { var self = this;
self._destroy();
self.fullUrl = "ws://" + self.url + "?" + $.param($.extend(self.settings.params, { version: self.version }));
self._debug("connection attempt to " + self.fullUrl);
if (window.MozWebSocket) self.ws = new MozWebSocket(self.fullUrl);
else if (window.WebSocket) self.ws = new WebSocket(self.fullUrl);
else self.ws = {
send: function(m){ return false },
close: function(){}
};
$(self.ws)
.bind('open', function() {
self._debug("connected to " + self.fullUrl);
if (self.offlineTimeout) clearTimeout(self.offlineTimeout);
if (self.options.offlineTag) self.options.offlineTag.hide();
self.settings.open();
})
.bind('close', function() {
self._debug("disconnected");
if (self.options.offlineDelay && !self.offlineTimeout) self.offlineTimeout = setTimeout(function() {
if (self.options.offlineTag) self.options.offlineTag.show();
}, self.options.offlineDelay);
self.settings.close();
})
.bind('message', function(e){
var m = JSON.parse(e.originalEvent.data);
if (m.t == "n") {
self.keepAlive();
} else {
self._debug(m);
}
if (m.t == "batch") {
$(m.d || []).each(function() { self._handle(this); });
} else {
self._handle(m);
}
});
self.keepAlive();
},
keepAlive: function() {
var self = this;
clearTimeout(self.pingTimeout);
setTimeout(function() {
try {
self.ws.send(self.options.pingData);
self.pingTimeout = setTimeout(function() {
self._debug("reconnect!");
self.connect();
}, self.options.pingTimeout);
} catch (e) {
self._debug(e);
self.connect();
}
}, self.options.pingDelay);
},
send: function(t, d) {
var data = d || {};
this._debug({t: t, d: data});
return this.ws.send(JSON.stringify({t: t, d: data}));
},
disconnect: function() {
this.ws.close();
},
_handle: function(m) { var self = this;
if (m.v) self.version = m.v;
var h = self.settings.events[m.t];
if ($.isFunction(h)) h(m.d || null);
else self._debug(m.t + " not supported");
self.settings.message(m);
},
_debug: function(msg) { if (this.options.debug) console.debug("[" + this.options.name + "]", msg); },
_destroy: function() { if (this.ws) { this.disconnect(); this.ws = null; } }
}