From 3531d46cc3644a64b990f904e40e4846b8242a07 Mon Sep 17 00:00:00 2001 From: lassulus Date: Tue, 12 Nov 2013 02:01:29 +0100 Subject: webchat: refactor to rpc --- webchat/public/client.js | 75 ++++++++++++----------- webchat/public/commands.js | 11 ++-- webchat/public/functions.js | 20 +------ webchat/public/handler.js | 35 ----------- webchat/public/rpc.js | 99 +++++++++++++++++++++++++++++++ webchat/public/sockjs_client_transport.js | 27 +++++++++ 6 files changed, 172 insertions(+), 95 deletions(-) delete mode 100644 webchat/public/handler.js create mode 100644 webchat/public/rpc.js create mode 100644 webchat/public/sockjs_client_transport.js (limited to 'webchat/public') diff --git a/webchat/public/client.js b/webchat/public/client.js index 8f7becb7..8865fcc0 100644 --- a/webchat/public/client.js +++ b/webchat/public/client.js @@ -23,44 +23,43 @@ function request (settings, method, params, callback) { $(function connect() { settings.sock = new SockJS('/echo'); - - settings.sock.onopen = function() { - console.log('open'); - request(settings, 'coi', {}, function (error, result) { - if (error) { - console.log('coi error', error) - } else { - settings.nick = result.nick //TODO: write to display - settings.addr = result.addr //TODO: write to display - } - }) - }; - settings.sock.onmessage = function(e) { - console.log('message', e.data); - try { - var object = JSON.parse(e.data); - console.log(object); - - } catch (error) { - console.log(error); - throw error; - } - if (typeof object.method === 'string') { - return methodDispatcher(settings, object); - } else if (typeof object.result === 'string') { - return resultDispatcher(settings, object); - } else { - console.log('bad message:', object) - } - } - settings.sock.onclose = function(event) { - console.log('close'); - switch (event.code) { - case 1006: //abnormal closure - return setTimeout(connect, 1000); - }; - }; - + var transport = make_sockjs_client_transport(settings.sock) + var rpc = new RPC(transport) + rpc.register('msg', {type: 'string', nick: 'string', msg: 'string'}, function(params, callback) { + var safe_message = $('
').text(params.msg).html(); + safe_message = replaceURLWithHTMLLinks(safe_message); + var safe_from = $('
').text(params.nick).html(); + chatboxAppend(safe_from, safe_message, 'web_msg') + return callback(null) + }) + rpc.register('nick', {type: 'string', newnick: 'string', oldnick: 'string'}, function(params, callback) { + var safe_oldnick = $('
').text(params.oldnick).html(); + var safe_newnick = $('
').text(params.newnick).html(); + var safe_type = $('
').text(params.type).html(); + $(getNicklistElement(safe_oldnick,safe_type)).remove(); + $('#nicklist').append('
' + safe_newnick + '
') ; + chatboxAppend(safe_oldnick, 'is now known as ' + safe_newnick, 'nick'); + return callback(null) + }) + rpc.register('your_nick', {nick: 'string'}, function(params, callback) { + var safe_nick = $('
').text(params.nick).html(); + settings.nick = safe_nick + return callback(null) + }) + rpc.register('join', {type: 'string', nick: 'string'}, function(params, callback) { + var safe_nick = $('
').text(params.nick).html(); + var safe_type = $('
').text(params.type).html(); + $('#nicklist').append('
' + safe_nick + '
') ; + chatboxAppend(safe_nick, 'has joined'); + return callback(null) + }) + rpc.register('part', {type: 'string', nick: 'string'}, function(params, callback) { + var safe_nick = $('
').text(params.nick).html(); + var safe_type = $('
').text(params.type).html(); + $(getNicklistElement(safe_nick,safe_type)).remove(); + chatboxAppend(safe_nick, 'has parted'); + return callback(null) + }) }); $(function() { $('#input').keydown(function(e) { diff --git a/webchat/public/commands.js b/webchat/public/commands.js index 5a570556..d4408c4c 100644 --- a/webchat/public/commands.js +++ b/webchat/public/commands.js @@ -1,14 +1,15 @@ var commands = {} -commands.say = function (settings, params) { +commands.msg = function (settings, params) { var sendObj = { - method: 'say', - params: { msg: params }, - }; + method: 'msg', + params: { msg: params } + } settings.sock.send(JSON.stringify(sendObj)) } commands.nick = function (settings, params) { + settings.nick = params var sendObj = { method: 'nick', params: { nick: params }, @@ -17,7 +18,7 @@ commands.nick = function (settings, params) { } commands.badcommand = function (settings, params) { - console.log("error"); + console.log("error", params); chatboxAppend( 'error', 'command not found' ) diff --git a/webchat/public/functions.js b/webchat/public/functions.js index 45c8ad3f..244af67b 100644 --- a/webchat/public/functions.js +++ b/webchat/public/functions.js @@ -3,25 +3,11 @@ function inputParser (str) { if (match) { return { method: match[1], params: match[2] } } else { - return { method: 'say', params: str } + return { method: 'msg', params: str } } } -function methodDispatcher (settings, object) { - console.log('parser: ',object) - return (handler[object.method] || console.log)(settings, object.params) -}; - -function resultDispatcher (settings, object) { - console.log('parser: ',object) - var callback = settings.waiting_callbacks[object.id] - delete settings.waiting_callbacks[object.id] - if (typeof callback === 'function') { - callback(object.error, object.result) - } -}; - function replaceURLWithHTMLLinks (text) { var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; @@ -37,9 +23,9 @@ function setMaybeNick (input) { function sortNicklist () { }; -function getNicklistElement(name) { +function getNicklistElement(name, type) { var el; - $('.name').each(function (i,e) { + $('.'+type+'_name').each(function (i,e) { if (e.innerHTML === name) { if (typeof el !== 'undefined') { throw new Error('duplicate name: ' + name); diff --git a/webchat/public/handler.js b/webchat/public/handler.js deleted file mode 100644 index 0930646d..00000000 --- a/webchat/public/handler.js +++ /dev/null @@ -1,35 +0,0 @@ -var handler = {} - -handler.message = function(settings, object) { - var safe_message = $('
').text(object.msg).html(); - safe_message = replaceURLWithHTMLLinks(safe_message); - var safe_from = $('
').text(object.nick).html(); - return chatboxAppend(safe_from, safe_message, 'msg') -}; - -handler.join = function(settings, object) { - var safe_from = $('
').text(object.from).html(); - $('#nicklist').append('
' + safe_from + '
') ; - return chatboxAppend(safe_from, 'joined', 'join') -}; - -handler.quit = function(settings, object) { - var safe_from = $('
').text(object.from).html(); - $(getNicklistElement(safe_from)).remove(); - return chatboxAppend(safe_from, 'quit', 'quit') -}; - -handler.nicklist = function(settings, object) { - Object.keys(object.nicklist).forEach(function (nick) { - var hash_from = btoa(nick).replace(/=/g,'_'); - $('#nicklist').append('
' + nick + '
') ; - }); -}; - -handler.nickchange = function(settings, object) { - var safe_from = $('
').text(object.nick).html(); - var safe_newnick = $('
').text(object.newnick).html(); - $(getNicklistElement(safe_from)).remove(); - $('#nicklist').append('
' + safe_newnick + '
') ; - return chatboxAppend(safe_from, 'is now known as ' + safe_newnick, 'nick'); -}; diff --git a/webchat/public/rpc.js b/webchat/public/rpc.js new file mode 100644 index 00000000..8e911e1d --- /dev/null +++ b/webchat/public/rpc.js @@ -0,0 +1,99 @@ +try { + module.exports = RPC +} +catch(e){ +} + +function RPC (transport) { + this._id = 0 + this._waiting_callbacks = {} + this._methods = {} + this._transport = transport + + transport.onmessage = this.onmessage.bind(this) +} + +RPC.prototype.register = function (method, params, callback) { + this._methods[method] = callback +} + +RPC.prototype.send = function (method, params, callback) { + var message = { + method: method, + params: params, + } + if (callback) { + var id = ++this._id + this._waiting_callbacks[id] = callback + message.id = id + } + return this._transport.send(message) +} + +function _is_request (message) { + return typeof message.method === 'string' +} + +function _is_response (message) { + return message.hasOwnProperty('result') + || message.hasOwnProperty('error') +} + +RPC.prototype.onmessage = function (message) { + console.log('RPC message:', message) + if (_is_request(message)) { + return this._on_request(message) + } + if (_is_response(message)) { + return this._on_response(message) + } + return this._on_bad_message(message) +} + +RPC.prototype._on_request = function (request) { + var method = this._methods[request.method] || function(){ + console.log('method not found', request.method) + } + var params = request.params + var id = request.id + + var transport = this._transport + + if (typeof id === 'string' || typeof id === 'number' || id === null) { + return method(params, function (error, result) { + var response = { + id: id, + } + if (error) { + response.error = error + } else { + response.result = result + } + console.log('request:', request, '->', response) + return transport.send(response) + }) + } else { + return method(params, function (error, result) { + var response = { + id: id, + } + if (error) { + response.error = error + } else { + response.result = result + } + console.log('notification:', request, '->', response) + }) + } +} + +RPC.prototype._on_response = function (response) { + var result = response.result + var error = response.error + var id = response.id + + var callback = this._waiting_callbacks[id] + delete this._waiting_callbacks[id] + + return callback(result, error) +} diff --git a/webchat/public/sockjs_client_transport.js b/webchat/public/sockjs_client_transport.js new file mode 100644 index 00000000..4e525d0d --- /dev/null +++ b/webchat/public/sockjs_client_transport.js @@ -0,0 +1,27 @@ + +function make_sockjs_client_transport (sock) { + var transport = {} + + sock.onmessage = function (data) { + console.log('sockjs parse', data) + try { + var message = JSON.parse(data.data) + } catch (error) { + return console.log('error', error) + } + transport.onmessage(message) + } + + transport.send = function (message) { + try { + var data = JSON.stringify(message) + } catch (error) { + return console.log('sockjs transport send error:', error) + } + sock.send(data) + } + + return transport +} + + -- cgit v1.2.3