LP#1268619: websocket js
authorBill Erickson <berick@esilibrary.com>
Mon, 10 Dec 2012 16:10:58 +0000 (11:10 -0500)
committerBill Erickson <berick@esilibrary.com>
Sun, 4 May 2014 20:10:34 +0000 (16:10 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
src/javascript/opensrf.js
src/javascript/opensrf_ws.js

index c4ccd2e..813bef8 100644 (file)
@@ -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);
             }
         }
     }
index 79c80f4..62302be 100644 (file)
@@ -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, '');
-    }
-};