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:
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
);
};
});
};
-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() {
}
// 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) {
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);
}
}
}
}
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);
}
}
}
// 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
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();
* 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:
} 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
}
);
OpenSRF.WebSocketRequest.prototype.send = function(message) {
- this.last_message = message;
-
var wrapper = {
service : this.session.service,
thread : this.session.thread,
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, '');
- }
-};