function Hara() { this.send_message_ids = {}; this.onopen = this.onclose = this.onerror = this.onmessage = function(){}; } Hara.prototype.send = function(action, args, callback){ var id = Hara.uuid(); var message = Hara.encode({_id: id, action: action, args: args}); this.send_message_ids[id] = callback; this.websocket.send(message); } Hara.prototype.connect = function(url, protocol){ this.websocket = new WebSocket(url, protocol); this.setup_callbacks(); } Hara.prototype.setup_callbacks = function(){ var that = this; this.websocket.onopen = function(){ that.onopen.apply(that, arguments); }; this.websocket.onclose = function(){ that.onclose.apply(that, arguments); }; this.websocket.onerror = function(){ that.onerror.apply(that, arguments); }; this.websocket.onmessage = function(msg){ var message = Hara.decode(msg.data); switch(message.type){ case 'response': that.handle_response(message); break; case 'push': that.handle_push(message); break; default: throw 'Unknown message type' } }; }; Hara.prototype.handle_response = function(message) { var id = message._id; var args = message.args; var callback = this.send_message_ids[id]; if(callback) { callback.apply(this, [args]); } delete this.send_message_ids[id]; }; Hara.prototype.handle_push = function(message) { var args = message.args; this.onmessage(args); }; Hara.prototype.close = function(){ this.websocket.close.apply(this.websocket, arguments); this.send_message_ids = {}; } Hara.uuid = function() { var uuid = ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); })); return uuid; } Hara.encode = function(args) { return JSON.stringify(args); } Hara.decode = function(args){ return JSON.parse(args); }