JavaXT
|
|
WebSocket Classif(!javaxt) var javaxt={}; if(!javaxt.dhtml) javaxt.dhtml={}; //****************************************************************************** //** WebSocket //*****************************************************************************/ /** * Used to communicate with a server using web sockets. Currently, this is a * read-only listener designed to get updates and status messages from the * server. The listener will automatically reconnect to the server if the * network connnection is interrupted. <pre> var ws = new javaxt.dhtml.WebSocket({ url: "/live/stats", onMessage: function(msg){ console.log(msg); } }); var logout = function(){ ws.stop(); //stop listening to events and disconnect from the server }; </pre> * ******************************************************************************/ javaxt.dhtml.WebSocket = function(config) { var me = this; var defaultConfig = { /** Relative path the to websocket endpoint (e.g. "/updates"). You do not * need to specify a full url with a "ws://" or "wss://" prefix. */ url: "", /** Interval used to check whether the websocket is still alive and send * ping messages. Value is in milliseconds. Default is 15000 (15 seconds). */ keepAlive: 15000, /** Class used to debug the websocket. This config is not required to use * this class. Implementations must implement an append() method. */ debugr : { append: function(msg){ //console.log(msg); } } }; var socket; var timer; var connectionSuccess = false; //************************************************************************** //** init //************************************************************************** var init = function(){ //Clone the config so we don't modify the original config object var clone = {}; javaxt.dhtml.utils.merge(clone, config); //Merge clone with default config javaxt.dhtml.utils.merge(clone, defaultConfig); config = clone; //Update events handlers for (var key in config) { if (config.hasOwnProperty(key)){ if (typeof config[key] == "function") { if (me[key] && typeof me[key] == "function"){ me[key] = config[key]; } } } } //Get debugger var debugr = config.debugr; //Set url to websocket endpoint var protocol = window.location.protocol.toLowerCase(); if (protocol.indexOf("https")===0) protocol = "wss"; else protocol = "ws"; var url = protocol + '://' + window.location.host; if (config.url.indexOf("/")!==0) url += "/"; var path = config.url; if (path){ var idx = path.indexOf("//"); if (idx>=0){ path = path.substring(idx+2); idx = path.indexOf("/"); if (idx>-1) path = path.substring(idx+1); } url += path; } var connect = function(){ var connectionStatusTimer; if (timer) clearInterval(timer); timer = setInterval(function() { if (socket){ if (socket.readyState === WebSocket.OPEN) { socket.send(''); } else if (socket.readyState === WebSocket.CLOSED){ connect(); } } }, config.keepAlive); socket = new WebSocket(url); socket.onopen = function(){ debugr.append("onopen"); //Update the connectionSuccess variable after a small delay. This //gives us a chance to see if the socket closes immediately after //open (see onclose) connectionStatusTimer = setTimeout(function(){ connectionSuccess = true; }, 500); me.onConnect(); }; //Handle messages sent by the server socket.onmessage = function(event) { connectionSuccess = true; var msg = event.data; debugr.append(msg); me.onMessage(msg); }; //Reconnect on disconnect socket.onclose = function(event){ debugr.append("onclose"); debugr.append(event.code + ": " + event.reason); if (connectionSuccess){ //Reconnect! me.onDisconnect(); connect(); } else{ //Websocket failed! debugr.append("Websocket failed"); socket = null; clearTimeout(timer); clearTimeout(connectionStatusTimer); me.onFailure(event.code, event.reason); me.onDisconnect(); } }; socket.onerror = function(){ debugr.append("error!"); }; }; connect(); }; //************************************************************************** //** onConnect //************************************************************************** /** Called whenever a websocket connection is established with the server. * Note that this event will be fired whenever a connection is dropped and * then restablished. */ this.onConnect = function(){}; //************************************************************************** //** onDisconnect //************************************************************************** /** Called whenever a websocket connection is closed or severed. */ this.onDisconnect = function(){}; //************************************************************************** //** onMessage //************************************************************************** /** Called whenever a message is recieved from the server. */ this.onMessage = function(msg){}; //************************************************************************** //** onFailure //************************************************************************** /** Called whenever there is a problem connecting or reconnecting to the * server. */ this.onFailure = function(code, reason){}; //************************************************************************** //** stop //************************************************************************** /** Used to stop listening to events and close the websocket */ this.stop = function(){ connectionSuccess = false; if (timer) clearInterval(timer); if (socket) socket.close(); }; init(); }; |