LP#1268619: websocket JS additions
authorBill Erickson <berick@esilibrary.com>
Thu, 8 Nov 2012 17:36:16 +0000 (12:36 -0500)
committerBill Erickson <berick@esilibrary.com>
Sun, 4 May 2014 20:10:33 +0000 (16:10 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
src/javascript/opensrf.js
src/javascript/opensrf_ws.js

index 408f0af..4287a57 100644 (file)
@@ -206,9 +206,8 @@ OpenSRF.Session = function() {
     this.state = OSRF_APP_SESSION_DISCONNECTED;
 };
 
-OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS;
-if (true || typeof WebSocket == 'undefined')
-    OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_XHR;
+//OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS;
+OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_XHR;
 
 OpenSRF.Session.cache = {};
 OpenSRF.Session.find_session = function(thread_trace) {
@@ -238,17 +237,11 @@ OpenSRF.Session.prototype.send_xhr = function(osrf_msg, args) {
 };
 
 OpenSRF.Session.prototype.send_ws = function(osrf_msg, args) {
-    args.session = this;
-    if (this.websocket) {
-        this.websocket.args = args; // callbacks
-        this.websocket.send(osrf_msg);
-    } else {
-        this.websocket = new OpenSRF.WSRequest(
-            this, args, function(wsreq) {
-                wsreq.send(osrf_msg);
-            }
-        );
-    }
+    new OpenSRF.WSRequest(
+        this, args, function(wsreq) {
+            wsreq.send(osrf_msg);
+        }
+    );
 };
 
 OpenSRF.Session.prototype.send_xmpp = function(osrf_msg, args) {
index d522834..808e10c 100644 (file)
  * GNU General Public License for more details.
  * ----------------------------------------------------------------------- */
 
-var WS_PATH = '/osrf-websocket';
+var WEBSOCKET_URL_PATH = '/osrf-websocket-translator';
+var WEBSOCKET_PORT = 7680;
+var WEBSOCKET_PORT_SSL = 7682;
+var wsConnections = {};
+
+
+// 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(handlers, connectArgs) {
+    connectArgs = connectArgs || {};
+    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;
+    this.path = proto + '://' + host + ':' + port + path;
+
+    this.setupSocket();
+    wsConnection[connectArgs.name] = this;
+}
 
 /**
- * onopen is required. no data can be sent 
- * until the async connection dance completes.
+ * create a new WebSocket.  useful for new connections or 
+ * applying a new socket to an existing connection (whose 
+ * socket was disconnected)
  */
-OpenSRF.WSRequest = function(session, args, onopen) {
-    this.session = session;
-    this.args = args;
-
-    var proto = location.protocol == 'https' ? 'wss' : 'ws';
-
-    var path = proto + '://' + location.host + 
-        WS_PATH + '?service=' + this.session.service;
+OpenSRF.WebSocketConnection.prototype.setupSocket = function() {
 
     try {
-        this.ws = new WebSocket(path);
+        this.socket = new WebSocket(this.path);
     } catch(e) {
-        throw new Error("WebSocket() not supported in this browser " + e);
+        throw new Error("WebSocket() not supported in this browser: " + e);
     }
 
+    this.socket.onopen = this.handlers.onopen;
+    this.socket.onmessage = this.handlers.onmessage;
+    this.socket.onerror = this.handlers.onerror;
+    this.socket.onclose = this.handlers.onclose;
+}
+
+/** shut it down */
+OpenSRF.WebSocketConnection.prototype.destroy = function() {
+    if (this.socket.readyState == this.socket.OPEN) {  
+        this.socket.close();
+    delete wsConnections[this.name];
+}
+
+/**
+ * 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;
+    this.session = session;
+    this.handlers = handlers;
+    this.setupConnection(connectionArgs || {});
+}
 
-    this.ws.onopen = function(evt) {
-        onopen(self);
-    }
+OpenSRF.WebSocketRequest.prototype.setupConnection = function(connectionArgs) {
 
-    this.ws.onmessage = function(evt) {
-        self.core_handler(evt.data);
-    }
+    var cname = connectionArgs.name || 'default';
+    this.wsc = wsConnections[cname];
 
-    this.ws.onerror = function(evt) {
-        self.transport_error_handler(evt.data);
-    }
+    if (this.wsc) { // we have a WebSocketConnection.  
+
+        if (this.wsc.socket.readyState == this.wsc.socket.CLOSED) { 
+            // reset the connection
+            this.wsc.setupSocket();
+
+        } else {
+
+            if (this.handlers.onopen) {
+                // socket is already open, but the user is expecting an onopen event
+                this.handlers.onopen(this);
+            }
+        }
 
-    this.ws.onclose = function(evt) {
+    } else { // no connection found
+
+        if (cname == 'default' || connectionArgs.useDefaultHandlers) { // create the default handle 
+
+            this.wsc = new OpenSRF.WebSocketConnection(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.onclose) self.onclose(self); 
+                }
+            });
+
+        } else {
+            throw new Error("No such WebSocketConnection '" + cname + "'");
+        }
     }
-};
+}
 
-OpenSRF.WSRequest.prototype.send = function(message) {
-    //console.log('sending: ' + js2JSON([message.serialize()]));
+
+OpenSRF.WebSocketRequest.prototype.send = function(message) {
+    console.log('sending: ' + js2JSON([message.serialize()]));
     this.last_message = message;
-    this.ws.send(js2JSON([message.serialize()]));
+    this.wsc.socket.send(js2JSON([message.serialize()]));
     return this;
 };
 
-OpenSRF.WSRequest.prototype.close = function() {
-    try { this.ws.close(); } catch(e) {}
-}
-
-OpenSRF.WSRequest.prototype.core_handler = function(json) {
-    //console.log('received: ' + json);
+OpenSRF.WebSocketRequest.prototype.core_handler = function(json) {
+    console.log('received: ' + json);
 
     OpenSRF.Stack.push(
         new OpenSRF.NetMessage(null, null, '', json),
         {
-            onresponse : this.args.onresponse,
-            oncomplete : this.args.oncomplete,
-            onerror : this.args.onerror,
+            onresponse : this.handlers.onresponse,
+            oncomplete : this.handlers.oncomplete,
+            onerror : this.handlers.onerror,
             onmethoderror : this.method_error_handler()
         },
-        this.args.session
+        this.handlers.session
     );
 };
 
 
-OpenSRF.WSRequest.prototype.method_error_handler = function() {
+OpenSRF.WebSocketRequest.prototype.method_error_handler = function() {
     var self = this;
     return function(req, status, status_text) {
-        if(self.args.onmethoderror) 
-            self.args.onmethoderror(req, status, status_text);
+        if(self.handlers.onmethoderror) 
+            self.handlers.onmethoderror(req, status, status_text);
 
-        if(self.args.onerror)  {
-            self.args.onerror(
+        if(self.handlers.onerror)  {
+            self.handlers.onerror(
                 self.last_message, self.session.service, '');
         }
     };
 };
 
-OpenSRF.WSRequest.prototype.transport_error_handler = function(msg) {
-    if(this.args.ontransporterror) {
-        this.args.ontransporterror(msg);
+OpenSRF.WebSocketRequest.prototype.transport_error_handler = function(msg) {
+    if(this.handlers.ontransporterror) {
+        this.handlers.ontransporterror(msg);
     }
-    if(this.args.onerror) {
-        this.args.onerror(msg, this.session.service, '');
+    if(this.handlers.onerror) {
+        this.handlers.onerror(msg, this.session.service, '');
     }
 };