click to refresh issue
[namibia] / public / js / app / websocket.js
1 /**
2  * Websocket protocol handler.
3  */
4 ;
5 (function () {
6
7         window._ = {};
8         _.Api = {};
9         _.Api.websocket =
10         {
11
12
13                 /**
14                  * URI of the websocket server.
15                  * @type {String}
16                  */
17                 _serverUri: null,
18                 /**
19                  * The socket.
20                  * @type {Object}
21                  */
22                 _socket: null,
23                 /**
24                  * State of things.
25                  * @type {String}
26                  */
27                 _state: 'closed',
28                 /**
29                  * Latency function to estimate latency and keep connection alive.
30                  * @type {Function}
31                  */
32                 _latencyChecker: null,
33                 /**
34                  * Latency check start time.
35                  * @type {Date}
36                  */
37                 _pingStart: null,
38                 /**
39                  * Latency.
40                  * @type {Array}
41                  */
42                 _latencies: [],
43                 /**
44                  * Latency.
45                  * @type {Integer}
46                  */
47                 _latencyAverage: 0,
48                 /**
49                  * Message processor callback.
50                  * @type {Function}
51                  */
52                 _messageCallback: function(){},
53                 /**
54                  * Connection opened callback.
55                  * @type {Function}
56                  */
57                 _connectionOpenedCallback: function(){},
58                 /**
59                  * Connection closed callback.
60                  * @type {Function}
61                  */
62                 _connectionClosedCallback: function(){},
63
64
65                 /**
66                  * Initialize instance.
67                  * @return {}
68                  */
69         _initialize: function ()
70         {
71             //-- Establish server uri and connect.
72             bug.info('Websocket', '_initialize', 'Initializing websocket submodule.');
73
74             //_.Api.websocket._serverUri = 'ws://' + window.location.hostname + ':' + window.location.port;
75             _.Api.websocket._serverUri = 'ws://' + window.location.hostname;
76             bug.dump('Websocket', '_initialize', 'Server URI: ' + _.Api.websocket._serverUri);
77             _.Api.websocket._state = 'open';
78             _.Api.websocket.connect();
79         },
80
81                 /**
82                  * Connect to websocket server.
83                  */
84                 connect: function ()
85                 {
86                         //-- Create a new websocket instance.
87                         _.Api.websocket._socket = new WebSocket(_.Api.websocket._serverUri);
88
89                         //-- Handle open event.
90                         _.Api.websocket._socket.onopen = function (ev)
91                         {
92                                 _.Api.websocket._state = 'open';
93                                 _.Api.websocket._latencyChecker = setInterval(function ()
94                                 {
95                                         if (WebSocket.OPEN == _.Api.websocket._socket.readyState)
96                                         {
97                                                 _.Api.websocket._pingStart = new Date();
98                                                 _.Api.websocket._socket.send('{"ping":true}');
99                                         }
100                                 }, 540000);
101                                 _.Api.websocket._connectionOpenedCallback();
102                                 bug.info('Websocket', '_connect', 'Connection established with ' + _.Api.websocket._serverUri + '.');
103                         }
104
105                         //-- Handle message event.
106                         _.Api.websocket._socket.onmessage = function (ev)
107                         {
108                                 var message = JSON.parse(ev.data);
109                                 bug.info('Websocket', 'received', message);
110                                 if (message.pong)
111                                 {
112                                         var _pingEnd = new Date();
113                                         _.Api.websocket._latencies.push((_pingEnd.getTime() - _.Api.websocket._pingStart.getTime()) / 2);
114                                         if (10 < _.Api.websocket._latencies.length)
115                                         {
116                                                 _.Api.websocket._latencies.shift();
117                                         }
118                                         var sum = _.Api.websocket._latencies.reduce(function (a, b) { return a + b; });
119                                         _.Api.websocket._latencyAverage = sum / _.Api.websocket._latencies.length;
120                                         bug.info('Websocket', 'latency', _.Api.websocket._latencyAverage);
121                                 }
122                                 else
123                                 {
124                                         _.Api.websocket._messageCallback(message);
125                                 }
126                         };
127
128                         //-- Handle error event.
129                         _.Api.websocket._socket.onerror = function (ev)
130                         {
131                                 bug.warn('Websocket', '_connect', ev);
132                         };
133
134                         //-- Handle close event.
135                         _.Api.websocket._socket.onclose = function (ev)
136                         {
137                                 _.Api.websocket._socket = null;
138                                 clearInterval(_.Api.websocket._latencyChecker);
139                                 _.Api.websocket._connectionClosedCallback();
140                                 if ('closed' == _.Api.websocket._state)
141                                 {
142                                         return;
143                                 }
144                                 bug.info('Websocket', '_connect.onclose', 'Connection closed.');
145                                 bug.dump('Websocket', '_connect.onclose', ev);
146                                 setTimeout(function () {
147                                                 $.proxy(_.Api.websocket.connect, _.Api.websocket)()
148                                         },
149                                         15000
150                                 );
151                         };
152                 },
153
154                 close: function ()
155                 {
156                         _.Api.websocket._state = 'closed';
157                         _.Api.websocket._socket.close();
158                 }
159
160
161         };
162
163 })();