LP#1268619: websockets: auto-upgrade to shared workers; SSL-always
[OpenSRF.git] / src / javascript / opensrf_ws.js
1 /* -----------------------------------------------------------------------
2  * Copyright (C) 2014  Equinox Software, Inc.
3  * Bill Erickson <berick@esilibrary.com>
4  *  
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ----------------------------------------------------------------------- */
15
16
17 var WEBSOCKET_URL_PATH = '/osrf-websocket-translator';
18 var WEBSOCKET_PORT_SSL = 7682;
19
20 OpenSRF.WebSocket = function() {
21     this.pending_messages = [];
22 }
23
24 /**
25  * If our global socket is already open, use it.  Otherwise, queue the 
26  * message for delivery after the socket is open.
27  */
28 OpenSRF.WebSocket.prototype.send = function(message) {
29     var self = this;
30
31     if (this.socket && this.socket.readyState == this.socket.OPEN) {
32         // this.socket connection is viable.  send our message now.
33         this.socket.send(message);
34         return;
35     }
36
37     // no viable connection. queue our outbound messages for future delivery.
38     this.pending_messages.push(message);
39     console.log('pending count ' + this.pending_messages.length);
40
41     if (this.socket && this.socket.readyState == this.socket.CONNECTING) {
42         // we are already in the middle of a setup call.  
43         // our queued message will be delivered after setup completes.
44         return;
45     }
46
47     // we have no websocket or an invalid websocket.  build a new one.
48
49     var path = 'wss://' + location.host + ':' + 
50         WEBSOCKET_PORT_SSL + WEBSOCKET_URL_PATH;
51
52     console.debug('connecting websocket to ' + path);
53
54     try {
55         this.socket = new WebSocket(path);
56     } catch(E) {
57         console.log('Error creating WebSocket for path ' + path + ' : ' + E);
58         throw new Error(E);
59     }
60
61     this.socket.onopen = function() {
62         console.debug('websocket.onopen()');
63         // deliver any queued messages
64         var msg;
65         console.log('pending count ' + self.pending_messages.length);
66         while ( (msg = self.pending_messages.shift()) )
67             self.socket.send(msg);
68     }
69
70     this.socket.onmessage = function(evt) {
71         self.onmessage(evt.data);
72     }
73
74     /**
75      * Websocket error handler.  This type of error indicates a probelem
76      * with the connection.  I.e. it's not port-specific. 
77      * Broadcast to all ports.
78      */
79     this.socket.onerror = function(evt) {
80         var err = "WebSocket Error " + evt + ' : ' + evt.data;
81         self.socket.close(); // connection is no good; reset.
82         throw new Error(err); 
83     }
84
85     /**
86      * Called when the websocket connection is closed.
87      *
88      * Once a websocket is closed, it will be re-opened the next time
89      * a message delivery attempt is made.  Clean up and prepare to reconnect.
90      */
91     this.socket.onclose = function() {
92         console.debug('closing websocket');
93         self.socket = null;
94     }
95 }