You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
6.8 KiB

  1. /**
  2. * Movim Websocket
  3. *
  4. * This file define the websocket behaviour and handle its connection
  5. */
  6. WebSocket.prototype.unregister = function() {
  7. this.send(JSON.stringify({'func' : 'unregister'}));
  8. };
  9. WebSocket.prototype.register = function(host) {
  10. this.send(JSON.stringify({'func' : 'register', 'host' : host}));
  11. };
  12. /*WebSocket.prototype.admin = function(key) {
  13. this.send(JSON.stringify({'func' : 'admin', 'key' : key}));
  14. };*/
  15. /**
  16. * @brief Definition of the MovimWebsocket object
  17. * @param string error
  18. */
  19. var MovimWebsocket = {
  20. connection: null,
  21. attached: new Array(),
  22. registered: new Array(),
  23. attempts: 1,
  24. pong: false,
  25. launchAttached : function() {
  26. // We hide the Websocket error
  27. MovimUtils.hideElement(document.getElementById('error_websocket'));
  28. for(var i = 0; i < MovimWebsocket.attached.length; i++) {
  29. MovimWebsocket.attached[i]();
  30. }
  31. },
  32. launchRegistered : function() {
  33. for(var i = 0; i < MovimWebsocket.registered.length; i++) {
  34. MovimWebsocket.registered[i]();
  35. }
  36. },
  37. init : function() {
  38. if(SECURE_WEBSOCKET) {
  39. var uri = 'wss://' + BASE_HOST + '/ws/';
  40. } else {
  41. var uri = 'ws://' + BASE_HOST + '/ws/';
  42. }
  43. if(this.connection
  44. && this.connection.readyState == 1) {
  45. this.connection.onclose = null;
  46. this.connection.close();
  47. }
  48. this.connection = new WebSocket(uri + '?path=' + MovimUtils.urlParts().page);
  49. this.connection.onopen = function(e) {
  50. console.log("Connection established!");
  51. MovimWebsocket.attempts = 1;
  52. MovimWebsocket.launchAttached();
  53. setTimeout(function(){
  54. MovimWebsocket.ping();
  55. }, 15000);
  56. };
  57. this.connection.onmessage = function(e) {
  58. data = pako.ungzip(MovimUtils.base64Decode(e.data), { to: 'string' });
  59. var obj = JSON.parse(data);
  60. if(obj != null) {
  61. if(obj.func == 'registered') {
  62. MovimWebsocket.launchRegistered();
  63. }
  64. if(obj.func == 'disconnected') {
  65. MovimUtils.disconnect();
  66. }
  67. if(obj.func == 'pong') {
  68. MovimWebsocket.pong = true;
  69. }
  70. if(obj.func == 'block') {
  71. MovimWebsocket.clearAttached();
  72. MovimUtils.addClass('body', 'disabled');
  73. }
  74. MovimWebsocket.handle(obj);
  75. }
  76. };
  77. this.connection.onclose = function(e) {
  78. console.log("Connection closed by the server or session closed");
  79. if(e.code == 1006) {
  80. MovimWebsocket.reconnect();
  81. } else if(e.code == 1000) {
  82. MovimUtils.disconnect();
  83. }
  84. };
  85. this.connection.onerror = function(e) {
  86. console.log("Connection error!");
  87. // We hide the Websocket error
  88. MovimUtils.showElement(document.getElementById('error_websocket'));
  89. MovimWebsocket.reconnect();
  90. // We prevent the onclose launch
  91. this.onclose = null;
  92. };
  93. },
  94. send : function(widget, func, params) {
  95. if(this.connection.readyState == 1) {
  96. this.connection.send(
  97. JSON.stringify(
  98. {'func' : 'message', 'body' :
  99. {
  100. 'widget' : widget,
  101. 'func' : func,
  102. 'params' : params
  103. }
  104. }
  105. )
  106. );
  107. }
  108. },
  109. // A ping/pong system to handle socket errors for buggy browser (Chrome on Linux…)
  110. ping : function() {
  111. if(this.connection.readyState == 1) {
  112. this.connection.send(
  113. JSON.stringify(
  114. {'func' : 'ping'}
  115. )
  116. );
  117. setTimeout(function(){
  118. if(MovimWebsocket.pong == false) {
  119. MovimWebsocket.connection.onerror();
  120. } else {
  121. MovimWebsocket.pong = false;
  122. MovimWebsocket.ping();
  123. }
  124. }, 15000);
  125. }
  126. },
  127. attach : function(func) {
  128. if(typeof(func) === "function") {
  129. this.attached.push(func);
  130. }
  131. },
  132. register : function(func) {
  133. if(typeof(func) === "function") {
  134. this.registered.push(func);
  135. }
  136. },
  137. clearAttached : function() {
  138. this.attached = new Array();
  139. },
  140. handle : function(funcalls) {
  141. if(funcalls != null) {
  142. for(h = 0; h < funcalls.length; h++) {
  143. var funcall = funcalls[h];
  144. if(funcall.func != null && (typeof window[funcall.func] == 'function')) {
  145. try {
  146. window[funcall.func].apply(null, funcall.params);
  147. } catch(err) {
  148. console.log("Error caught: " + err.toString() + " - " + funcall.func + ":" + JSON.stringify(funcall.params));
  149. }
  150. } else if(funcall.func != null) {
  151. var funcs = funcall.func.split('.');
  152. var called = funcs[0];
  153. if(typeof window[called] == 'object') {
  154. window[funcs[0]][funcs[1]].apply(null, funcall.params);
  155. }
  156. }
  157. }
  158. }
  159. },
  160. unregister : function(reload) {
  161. this.connection.unregister();
  162. },
  163. reconnect : function() {
  164. var interval = MovimWebsocket.generateInterval();
  165. console.log("Try to reconnect");
  166. setTimeout(function () {
  167. // We've tried to reconnect so increment the attempts by 1
  168. MovimWebsocket.attempts++;
  169. // Connection has closed so try to reconnect every 10 seconds.
  170. MovimWebsocket.init();
  171. }, interval);
  172. },
  173. generateInterval :function() {
  174. var maxInterval = (Math.pow(2, MovimWebsocket.attempts) - 1) * 1000;
  175. if (maxInterval > 30*1000) {
  176. maxInterval = 30*1000; // If the generated interval is more than 30 seconds, truncate it down to 30 seconds.
  177. }
  178. // generate the interval to a random number between 0 and the maxInterval determined from above
  179. return Math.random() * maxInterval;
  180. }
  181. }
  182. /*
  183. document.addEventListener("visibilitychange", function () {
  184. if(!document.hidden) {
  185. if(MovimWebsocket.connection.readyState == 3) {
  186. MovimWebsocket.init();
  187. }
  188. }
  189. });
  190. */
  191. window.onbeforeunload = function() {
  192. MovimWebsocket.connection.onclose = function () {}; // disable onclose handler first
  193. MovimWebsocket.connection.close()
  194. };
  195. movim_add_onload(function() {
  196. // And we start it
  197. MovimWebsocket.init();
  198. });