74fc40eedb1b53e7721ee36caeac05e7e9ea8246
[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 OpenSRF.WebSocket.prototype.connected = function() {
25     return (
26         this.socket && 
27         this.socket.readyState == this.socket.OPEN
28     );
29 }
30
31 /**
32  * If our global socket is already open, use it.  Otherwise, queue the 
33  * message for delivery after the socket is open.
34  */
35 OpenSRF.WebSocket.prototype.send = function(message) {
36     var self = this;
37
38     if (this.connected()) {
39         // this.socket connection is viable.  send our message now.
40         this.socket.send(message);
41         return;
42     }
43
44     // no viable connection. queue our outbound messages for future delivery.
45     this.pending_messages.push(message);
46     console.log('pending count ' + this.pending_messages.length);
47
48     if (this.socket && this.socket.readyState == this.socket.CONNECTING) {
49         // we are already in the middle of a setup call.  
50         // our queued message will be delivered after setup completes.
51         return;
52     }
53
54     // we have no websocket or an invalid websocket.  build a new one.
55
56     var path = 'wss://' + location.host + ':' + 
57         WEBSOCKET_PORT_SSL + WEBSOCKET_URL_PATH;
58
59     console.debug('connecting websocket to ' + path);
60
61     try {
62         this.socket = new WebSocket(path);
63     } catch(E) {
64         console.log('Error creating WebSocket for path ' + path + ' : ' + E);
65         throw new Error(E);
66     }
67
68     this.socket.onopen = function() {
69         console.debug('websocket.onopen()');
70         // deliver any queued messages
71         var msg;
72         console.log('pending count ' + self.pending_messages.length);
73         while ( (msg = self.pending_messages.shift()) )
74             self.socket.send(msg);
75     }
76
77     this.socket.onmessage = function(evt) {
78         self.onmessage(evt.data);
79     }
80
81     /**
82      * Websocket error handler.  This type of error indicates a probelem
83      * with the connection.  I.e. it's not port-specific. 
84      * Broadcast to all ports.
85      */
86     this.socket.onerror = function(evt) {
87         var err = "WebSocket Error " + evt + ' : ' + evt.data;
88         self.socket.close(); // connection is no good; reset.
89         throw new Error(err); 
90     }
91
92     /**
93      * Called when the websocket connection is closed.
94      *
95      * Once a websocket is closed, it will be re-opened the next time
96      * a message delivery attempt is made.  Clean up and prepare to reconnect.
97      */
98     this.socket.onclose = function() {
99         console.debug('closing websocket');
100         self.socket = null;
101         if (OpenSRF.onWebSocketClosed)
102             OpenSRF.onWebSocketClosed();
103     }
104 }