Last active
August 29, 2015 14:18
-
-
Save django-wong/f158570028bc87a2a5aa to your computer and use it in GitHub Desktop.
Websocket connecter - Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Common websocket connecter, only compliant with rapAthorus | |
* #events | |
* online | |
* offline | |
* onmessage | |
* connect_failed | |
* get_token_failed | |
* other custom events... | |
*/ | |
var Connecter = function(options){ | |
'use strict'; | |
options = options || {}; | |
this.token = options.token || undefined; | |
this.host = options.host || undefined; | |
this.port = options.port || 8081; | |
this.path = options.path || '/connect'; | |
this.get_token_counter = 0; | |
this.ws = undefined; | |
this.events = {}; | |
this.connected = undefined; | |
this.online = undefined; | |
this.queue = []; | |
this.retryCount = 0; | |
this.loginCount = 0; | |
var connecter = this; | |
connecter.getToken = function(cb) { | |
cb = cb || function(){}; | |
// connecter.get_token_counter++; | |
var options ={ | |
url: '/member/token', | |
cache: false, | |
dataType: 'json', | |
success: function(data){ | |
if(!data.error){ | |
connecter.get_token_counter = 0; | |
connecter.token = data.token; | |
connecter.expires = data.expires; | |
connecter.trigger('get_token_success', connecter.token); | |
} | |
cb.call(connecter); | |
}, | |
error: function(data){ | |
cb.call(connecter); | |
} | |
}; | |
connecter.ajax(options); | |
}; | |
connecter.getIPv4 = function(cb){ | |
var options ={ | |
url: '/home/ip', | |
async: false, | |
cache: false, | |
dataType: 'text', | |
success: function(data){ | |
connecter.host = data; | |
cb.call(connecter); | |
}, | |
error: function(data){ | |
cb.call(connecter); | |
} | |
}; | |
connecter.ajax(options); | |
}; | |
connecter.connect = function() { | |
connecter.retryCount ++; | |
if(!connecter.token && connecter.retryCount<3){ | |
connecter.getToken(connecter.connect); | |
return; | |
} | |
if(!connecter.host && connecter.retryCount<3){ | |
connecter.getIPv4(connecter.connect); | |
} | |
connecter.retryCount = 0; | |
if(connecter.ws && connecter.connected){ | |
connecter.ws.close(); | |
connecter.ws = undefined; | |
} | |
connecter.ws = new WebSocket("ws://"+connecter.host+":"+connecter.port+connecter.path); | |
connecter.ws.onopen = connecter.logon; | |
connecter.ws.onmessage = connecter.onmessage; | |
connecter.ws.onclose = connecter.onclose; | |
connecter.ws.onerror = connecter.onerror; | |
}; | |
connecter.logon = function(evt) { | |
connecter.loginCount = 0; | |
if(!connecter.connected){ | |
connecter.connected = true; | |
connecter.trigger('connected'); | |
console.log('connected'); | |
} | |
var logon_info = new connecter.message('logon'); | |
logon_info.signature = connecter.logonSignature(logon_info); | |
connecter.send(JSON.stringify(logon_info)); | |
}; | |
connecter.onmessage = function(evt) { | |
var message = evt.data; | |
connecter.trigger('onmessage', message); | |
try{ | |
message = JSON.parse(message); | |
}catch(e){ | |
message = evt.data; | |
} | |
if(typeof(message) === 'object'){ | |
if(message.handle !== undefined && message.handle !== ''){ | |
connecter.trigger(message.handle, message); | |
}else if(message.error){ | |
console.log(message.error); | |
if(message.code){ | |
switch(message.code){ | |
case 1:{ | |
if(connecter.loginCount < 5){ | |
connecter.loginCount +=1; | |
connecter.getToken(connecter.logon); | |
} | |
break; | |
} | |
case 2:{ | |
if(connecter.loginCount < 5){ | |
connecter.loginCount +=1; | |
connecter.getToken(connecter.logon); | |
} | |
break; | |
} | |
default :{ | |
connecter.trigger('onerror', message); | |
console.info('Unexpected error code'); | |
} | |
} | |
} | |
} | |
}else{ | |
switch(message){ | |
case 'logon_success': { | |
connecter.trigger('online'); | |
connecter.online = true; | |
connecter.process(); | |
break; | |
} | |
default: { | |
break; | |
} | |
} | |
} | |
}; | |
connecter.onclose = function(evt) { | |
connecter.connected = false; | |
connecter.online = false; | |
console.log('connection has been closed'); | |
connecter.trigger('offline'); | |
}; | |
connecter.onerror = function(evt) { | |
connecter.trigger('onerror', evt); | |
}; | |
/** | |
* Send text | |
* @param mixed data usual is meessage object or support json plaintext | |
* @return void | |
*/ | |
connecter.send = function(data, callback) { | |
if(connecter.ws.readyState !== 1){ | |
connecter.queue.push({'data': data, 'callback':callback}); | |
}else{ | |
if(typeof(data) !== 'string'){ | |
data = JSON.stringify(data); | |
} | |
connecter.ws.send(data); | |
if(callback && typeof(callback) == 'function'){ | |
callback.call(this); | |
} | |
} | |
}; | |
/** | |
* process the queue | |
* @return {[type]} [description] | |
*/ | |
connecter.process = function(){ | |
for(var i in connecter.queue){ | |
var q = connecter.queue[i]; | |
connecter.send(q.data, q.callback); | |
} | |
connecter.queue = []; | |
}; | |
/** | |
* Send a ajax request, alias for $.ajax() | |
* @param object o ajax options | |
* @return void | |
*/ | |
connecter.ajax = function(o){ | |
var options = { | |
}; | |
options = $.extend(options, o); | |
$.ajax(options); | |
}; | |
/** | |
* Output string | |
* @param string text | |
* @return void | |
*/ | |
connecter.alert = function(text) { | |
console.info(text); | |
}; | |
/** | |
* Get current time stamp | |
* @return int timestamp | |
*/ | |
connecter.currentTime = function(){ | |
return parseInt(new Date().valueOf()/1000); | |
}; | |
/** | |
* Signature a logon message | |
* @param object logon message object | |
* @return string signature | |
*/ | |
connecter.logonSignature = function(logon) { | |
var str = logon.token+logon.timestamp+''; | |
str = str.toLowerCase(); | |
var signature = MD5(str).toLowerCase(); | |
return signature; | |
}; | |
/** | |
* Trigger a custom event | |
* @param string event name | |
* @params any params you want deliver | |
* @return connecter | |
*/ | |
connecter.trigger = function(){ | |
var args = Array.prototype.slice.call(arguments); | |
var evt = args.shift(); | |
if(!connecter.events[evt]){ | |
connecter.events[evt] = []; | |
} | |
var es = connecter.events[evt]; | |
for (var j in es) { | |
var func = es[j]; | |
func.apply(connecter, args); | |
} | |
return connecter; | |
}; | |
/** | |
* bind a custom event | |
* @param string evt event name | |
* @param function callback | |
* @return connecter | |
*/ | |
connecter.bind = function(evt, callback){ | |
if(!connecter.events[evt]){ | |
connecter.events[evt] = []; | |
} | |
var e = connecter.events[evt]; | |
e.push(callback); | |
return connecter; | |
}; | |
/** | |
* unbind a custom event | |
* @param string evt event name | |
* @param function callback witch you want unbind | |
* @return connecter | |
*/ | |
connecter.unbind = function(evt, callback){ | |
if(evt === true){ | |
connecter.events = {}; | |
return connecter; | |
} | |
if(!connecter.events[evt]){ | |
return connecter; | |
} | |
if(callback === undefined){ | |
connecter.events[evt] = []; | |
return connecter; | |
} | |
var es = connecter.events[evt]; | |
for(var i in es){ | |
if(es[i] === callback){ | |
connecter.events[evt].splice(i,1); | |
} | |
} | |
connecter.alert(connecter.events); | |
return connecter; | |
}; | |
/** | |
* Standard message object | |
* @param string handle | |
* @param mixed body | |
* @return object | |
*/ | |
connecter.message = function(handle, body){ | |
if(connecter.expires < connecter.currentTime()){ | |
connecter.getToken(); | |
} | |
var data = { | |
'token' : connecter.token, | |
'timestamp' : connecter.currentTime(), | |
'body' : body, | |
'handle' : handle, | |
}; | |
return data; | |
}; | |
/** | |
* Handle login request | |
* @param object message should be a json object | |
* @return void | |
*/ | |
connecter.handle_login = function(message){ | |
if(message.body === 'success'){ | |
connecter.loginCount = 0; | |
connecter.trigger('online'); | |
connecter.online = true; | |
console.info('online'); | |
connecter.process(); | |
} | |
}; | |
/** | |
* init connecter, bind login handler | |
* @return connecter | |
*/ | |
connecter.init = function(){ | |
connecter.bind('login', connecter.handle_login); | |
return connecter; | |
}; | |
return connecter.init(); | |
}; | |
var conn = new Connecter({'host': ipaddress, 'token': token}); | |
conn.connect(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment