From 6c85553008ad8543f18cebc2a76efd1ff5bbef83 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 10 Dec 2012 11:10:58 -0500 Subject: [PATCH] LP#1268619: websocket js Signed-off-by: Bill Erickson --- src/javascript/opensrf.js | 93 +++++++++++++++++++------------------- src/javascript/opensrf_ws.js | 105 +++++++++++++++---------------------------- 2 files changed, 80 insertions(+), 118 deletions(-) diff --git a/src/javascript/opensrf.js b/src/javascript/opensrf.js index c4ccd2e..813bef8 100644 --- a/src/javascript/opensrf.js +++ b/src/javascript/opensrf.js @@ -221,7 +221,7 @@ OpenSRF.Session.prototype.send = function(osrf_msg, args) { args = (args) ? args : {}; switch(OpenSRF.Session.transport) { case OSRF_TRANSPORT_TYPE_WS: - return this.send_ws(osrf_msg, args); + return this.send_ws(osrf_msg); case OSRF_TRANSPORT_TYPE_XHR: return this.send_xhr(osrf_msg, args); case OSRF_TRANSPORT_TYPE_XMPP: @@ -236,16 +236,10 @@ OpenSRF.Session.prototype.send_xhr = function(osrf_msg, args) { new OpenSRF.XHRequest(osrf_msg, args).send(); }; -OpenSRF.Session.prototype.send_ws = function(osrf_msg, args) { +OpenSRF.Session.prototype.send_ws = function(osrf_msg) { new OpenSRF.WebSocketRequest( - this, { - onopen : function(wsreq) { wsreq.send(osrf_msg) }, - onresponse : args.onresponse, - oncomplete : args.oncomplete, - onerror : args.onerror, - onmethoderror : args.onmethoderror, - ontransporterror : args.ontransporterror, - } + this, + function(wsreq) {wsreq.send(osrf_msg)} // onopen ); }; @@ -410,11 +404,12 @@ OpenSRF.Request.prototype.send = function() { }); }; -OpenSRF.NetMessage = function(to, from, thread, body) { +OpenSRF.NetMessage = function(to, from, thread, body, osrf_msg) { this.to = to; this.from = from; this.thread = thread; this.body = body; + this.osrf_msg = osrf_msg; }; OpenSRF.Stack = function() { @@ -433,54 +428,59 @@ function log(msg) { } // ses may be passed to us by the network handler -OpenSRF.Stack.push = function(net_msg, callbacks, ses) { - if (!ses) ses = OpenSRF.Session.find_session(net_msg.thread); +OpenSRF.Stack.push = function(net_msg, callbacks) { + var ses = OpenSRF.Session.find_session(net_msg.thread); if (!ses) return; ses.remote_id = net_msg.from; - osrf_msgs = []; - - try { - osrf_msgs = JSON2js(net_msg.body); - - if (OpenSRF.Session.transport == OSRF_TRANSPORT_TYPE_WS) { - // WebSocketRequests wrap the content - osrf_msgs = osrf_msgs.osrf_msg; - } - } catch(E) { - log('Error parsing OpenSRF message body as JSON: ' + net_msg.body + '\n' + E); + // NetMessage's from websocket connections are parsed before they get here + osrf_msgs = net_msg.osrf_msg; - /** UGH - * For unknown reasons, the Content-Type header will occasionally - * be included in the XHR.responseText for multipart/mixed messages. - * When this happens, strip the header and newlines from the message - * body and re-parse. - */ - net_msg.body = net_msg.body.replace(/^.*\n\n/, ''); - log('Cleaning up and retrying...'); + if (!osrf_msgs) { try { osrf_msgs = JSON2js(net_msg.body); - } catch(E2) { - log('Unable to clean up message, giving up: ' + net_msg.body); - return; + + if (OpenSRF.Session.transport == OSRF_TRANSPORT_TYPE_WS) { + // WebSocketRequests wrap the content + osrf_msgs = osrf_msgs.osrf_msg; + } + + } catch(E) { + log('Error parsing OpenSRF message body as JSON: ' + net_msg.body + '\n' + E); + + /** UGH + * For unknown reasons, the Content-Type header will occasionally + * be included in the XHR.responseText for multipart/mixed messages. + * When this happens, strip the header and newlines from the message + * body and re-parse. + */ + net_msg.body = net_msg.body.replace(/^.*\n\n/, ''); + log('Cleaning up and retrying...'); + + try { + osrf_msgs = JSON2js(net_msg.body); + } catch(E2) { + log('Unable to clean up message, giving up: ' + net_msg.body); + return; + } } } // push the latest responses onto the end of the inbound message queue for(var i = 0; i < osrf_msgs.length; i++) - OpenSRF.Stack.queue.push({msg : osrf_msgs[i], callbacks : callbacks, ses : ses}); + OpenSRF.Stack.queue.push({msg : osrf_msgs[i], ses : ses}); // continue processing responses, oldest to newest while(OpenSRF.Stack.queue.length) { var data = OpenSRF.Stack.queue.shift(); - OpenSRF.Stack.handle_message(data.ses, data.msg, data.callbacks); + OpenSRF.Stack.handle_message(data.ses, data.msg); } }; -OpenSRF.Stack.handle_message = function(ses, osrf_msg, callbacks) { +OpenSRF.Stack.handle_message = function(ses, osrf_msg) { - var req = null; + var req = ses.find_request(osrf_msg.threadTrace()); if(osrf_msg.type() == OSRF_MESSAGE_TYPE_STATUS) { @@ -489,12 +489,11 @@ OpenSRF.Stack.handle_message = function(ses, osrf_msg, callbacks) { var status_text = payload.status(); if(status == OSRF_STATUS_COMPLETE) { - req = ses.find_request(osrf_msg.threadTrace()); if(req) { req.complete = true; - if(callbacks.oncomplete && !req.oncomplete_called) { + if(req.oncomplete && !req.oncomplete_called) { req.oncomplete_called = true; - return callbacks.oncomplete(req); + return req.oncomplete(req); } } } @@ -510,18 +509,16 @@ OpenSRF.Stack.handle_message = function(ses, osrf_msg, callbacks) { } if(status == OSRF_STATUS_NOTFOUND || status == OSRF_STATUS_INTERNALSERVERERROR) { - req = ses.find_request(osrf_msg.threadTrace()); - if(callbacks.onmethoderror) - return callbacks.onmethoderror(req, status, status_text); + if(req && req.onmethoderror) + return req.onmethoderror(req, status, status_text); } } if(osrf_msg.type() == OSRF_MESSAGE_TYPE_RESULT) { - req = ses.find_request(osrf_msg.threadTrace()); if(req) { req.response_queue.push(osrf_msg.payload()); - if(callbacks.onresponse) { - return callbacks.onresponse(req); + if(req.onresponse) { + return req.onresponse(req); } } } diff --git a/src/javascript/opensrf_ws.js b/src/javascript/opensrf_ws.js index 79c80f4..62302be 100644 --- a/src/javascript/opensrf_ws.js +++ b/src/javascript/opensrf_ws.js @@ -21,20 +21,20 @@ var WEBSOCKET_PORT_SSL = 7682; // Create the websocket and connect to the server // args.onopen is required -// if args.default is true, use the default handle inst -OpenSRF.WebSocketConnection = function(connectArgs, handlers) { - connectArgs = connectArgs || {}; +// if args.default is true, use the default connection +OpenSRF.WebSocketConnection = function(args, handlers) { + args = args || {}; this.handlers = handlers; - var secure = (connectArgs.ssl || location.protocol == 'https'); - var path = connectArgs.path || WEBSOCKET_URL_PATH; - var port = connectArgs.port || (secure ? WEBSOCKET_PORT_SSL : WEBSOCKET_PORT); - var host = connectArgs.host || location.host; + var secure = (args.ssl || location.protocol == 'https'); + var path = args.path || WEBSOCKET_URL_PATH; + var port = args.port || (secure ? WEBSOCKET_PORT_SSL : WEBSOCKET_PORT); + var host = args.host || location.host; var proto = (secure) ? 'wss' : 'ws'; this.path = proto + '://' + host + ':' + port + path; this.setupSocket(); - OpenSRF.WebSocketConnection.pool[connectArgs.name] = this; + OpenSRF.WebSocketConnection.pool[args.name] = this; }; // global pool of connection objects; name => connection map @@ -63,6 +63,22 @@ OpenSRF.WebSocketConnection.prototype.setupSocket = function() { this.socket.onclose = this.handlers.onclose; }; +/** default onmessage handler: push the message up the opensrf stack */ +OpenSRF.WebSocketConnection.default_onmessage = function(evt) { + console.log('receiving: ' + evt.data); + var msg = JSON2js(evt.data); + OpenSRF.Stack.push( + new OpenSRF.NetMessage( + null, null, msg.thread, null, msg.osrf_msg) + ); +}; + +/** default error handler */ +OpenSRF.WebSocketConnection.default_onerror = function(evt) { + throw new Error("WebSocket Error " + evt + ' : ' + evt.data); +}; + + /** shut it down */ OpenSRF.WebSocketConnection.prototype.destroy = function() { this.socket.close(); @@ -73,40 +89,35 @@ OpenSRF.WebSocketConnection.prototype.destroy = function() { * Creates the request object, but does not connect or send anything * until the first call to send(). */ -OpenSRF.WebSocketRequest = function(session, handlers, connectionArgs) { - var self = this; +OpenSRF.WebSocketRequest = function(session, onopen, connectionArgs) { this.session = session; - this.handlers = handlers; + this.onopen = onopen; this.setupConnection(connectionArgs || {}); } -OpenSRF.WebSocketRequest.prototype.setupConnection = function(connectionArgs) { +OpenSRF.WebSocketRequest.prototype.setupConnection = function(args) { var self = this; - var cname = connectionArgs.name || 'default'; + var cname = args.name || 'default'; this.wsc = OpenSRF.WebSocketConnection.pool[cname]; if (this.wsc) { // we have a WebSocketConnection. - console.log('socket readySate = ' + this.wsc.socket.readyState); switch (this.wsc.socket.readyState) { case this.wsc.socket.CONNECTING: // replace the original onopen handler with a new combined handler var orig_open = this.wsc.socket.onopen; this.wsc.socket.onopen = function() { - console.log('combined onopen'); orig_open(); - console.log('combined onopen 2'); - self.handlers.onopen(self); - console.log('combined onopen ' + self.handlers.onopen); + self.onopen(self); }; break; case this.wsc.socket.OPEN: // user is expecting an onopen event. socket is // already open, so we have to manufacture one. - this.handlers.onopen(this); + this.onopen(this); break; default: @@ -116,24 +127,14 @@ OpenSRF.WebSocketRequest.prototype.setupConnection = function(connectionArgs) { } else { // no connection found - if (cname == 'default' || connectionArgs.useDefaultHandlers) { // create the default handle + if (cname == 'default' || args.useDefaultHandlers) { // create the default handle this.wsc = new OpenSRF.WebSocketConnection( {name : cname}, { - onopen : function(evt) { - if (self.handlers.onopen) - self.handlers.onopen(self); - }, - onmessage : function(evt) { - self.core_handler(evt.data); - }, - onerror : function(evt) { - self.transport_error_handler(evt.data); - }, - onclose : function(evt) { - if (self.handlers.onclose) - self.handlers.onclose(self); - } + onopen : function(evt) {if (self.onopen) self.onopen(self)}, + onmessage : OpenSRF.WebSocketConnection.default_onmessage, + onerror : OpenSRF.WebSocketRequest.default_onerror, + onclose : OpenSRF.WebSocketRequest.default_onclose } ); @@ -145,8 +146,6 @@ OpenSRF.WebSocketRequest.prototype.setupConnection = function(connectionArgs) { OpenSRF.WebSocketRequest.prototype.send = function(message) { - this.last_message = message; - var wrapper = { service : this.session.service, thread : this.session.thread, @@ -161,40 +160,6 @@ OpenSRF.WebSocketRequest.prototype.send = function(message) { return this; }; -OpenSRF.WebSocketRequest.prototype.core_handler = function(json) { - OpenSRF.Stack.push( - new OpenSRF.NetMessage(null, null, this.session.thread, json), - { - onresponse : this.handlers.onresponse, - oncomplete : this.handlers.oncomplete, - onerror : this.handlers.onerror, - onmethoderror : this.method_error_handler() - }, - this.session - ); -}; - - -OpenSRF.WebSocketRequest.prototype.method_error_handler = function() { - var self = this; - return function(req, status, status_text) { - if(self.handlers.onmethoderror) - self.handlers.onmethoderror(req, status, status_text); - if(self.handlers.onerror) { - self.handlers.onerror( - self.last_message, self.session.service, ''); - } - }; -}; - -OpenSRF.WebSocketRequest.prototype.transport_error_handler = function(msg) { - if(this.handlers.ontransporterror) { - this.handlers.ontransporterror(msg); - } - if(this.handlers.onerror) { - this.handlers.onerror(msg, this.session.service, ''); - } -}; -- 2.11.0