websocket.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. 'use strict';
  2. const WebSocket = require('ws');
  3. const ipcRender = require('../ipc/render-proecss');
  4. let wsClient = null;
  5. let sendQueue = [];
  6. let pendingReconnect = null;
  7. let fireSendQueue = function () {
  8. while (sendQueue.length && wsClient && wsClient.readyState === WebSocket.OPEN) {
  9. const request = sendQueue.shift();
  10. wsClient.send(request.data);
  11. request.deferred.resolve();
  12. }
  13. };
  14. let clearSendQueue = function () {
  15. for (let i = sendQueue.length - 1; i >= 0; i--) {
  16. sendQueue[i].deferred.reject();
  17. sendQueue.splice(i, 1);
  18. }
  19. };
  20. let planToReconnect = function (rpcUrl, options) {
  21. if (pendingReconnect) {
  22. ipcRender.notifyRenderProcessLogWarn('[lib/websocket.planToReconnect] another reconnection is pending');
  23. return;
  24. }
  25. pendingReconnect = setTimeout(function () {
  26. if (wsClient == null) {
  27. ipcRender.notifyRenderProcessLogWarn('[lib/websocket.planToReconnect] websocket is null');
  28. pendingReconnect = null;
  29. return;
  30. }
  31. if (wsClient.readyState === WebSocket.CONNECTING || wsClient.readyState === WebSocket.OPEN) {
  32. ipcRender.notifyRenderProcessLogWarn('[lib/websocket.planToReconnect] websocket current state is already ' + wsClient.readyState);
  33. pendingReconnect = null;
  34. return;
  35. }
  36. reconnect(rpcUrl, options);
  37. pendingReconnect = null;
  38. }, options.reconnectInterval);
  39. ipcRender.notifyRenderProcessLogDebug('[lib/websocket.planToReconnect] next reconnection is pending in ' + options.reconnectInterval + "ms");
  40. };
  41. let init = function () {
  42. if (sendQueue.length) {
  43. clearSendQueue();
  44. }
  45. if (wsClient) {
  46. wsClient.onopen = null;
  47. wsClient.onclose = null;
  48. wsClient.onmessage = null;
  49. wsClient.terminate();
  50. wsClient = null;
  51. }
  52. };
  53. let connect = function (rpcUrl, options, onOpenCallback, onCloseCallback, onMessageCallback) {
  54. init();
  55. wsClient = new WebSocket(rpcUrl);
  56. wsClient.onopen = function () {
  57. onOpenCallback({
  58. client: wsClient,
  59. url: rpcUrl
  60. });
  61. fireSendQueue();
  62. };
  63. wsClient.onclose = function () {
  64. let autoReconnect = false;
  65. if (options.reconnectInterval > 0) {
  66. autoReconnect = true;
  67. planToReconnect(rpcUrl, options);
  68. }
  69. onCloseCallback({
  70. client: wsClient,
  71. url: rpcUrl,
  72. autoReconnect: autoReconnect
  73. });
  74. };
  75. wsClient.onmessage = function (event) {
  76. let message = null;
  77. if (event) {
  78. message = event.data;
  79. }
  80. onMessageCallback({
  81. client: wsClient,
  82. url: rpcUrl,
  83. success: true,
  84. message: message
  85. });
  86. };
  87. wsClient.onerror = function (event) {
  88. // Do Nothing
  89. };
  90. };
  91. let reconnect = function (rpcUrl, options) {
  92. if (!wsClient) {
  93. return;
  94. }
  95. const onOpenFn = wsClient.onopen;
  96. const onCloseFn = wsClient.onclose;
  97. const onMessageFn = wsClient.onmessage;
  98. const onErrorFn = wsClient.onerror;
  99. init();
  100. wsClient = new WebSocket(rpcUrl);
  101. wsClient.onopen = onOpenFn;
  102. wsClient.onclose = onCloseFn;
  103. wsClient.onmessage = onMessageFn;
  104. wsClient.onerror = onErrorFn;
  105. };
  106. let send = function (requestContext) {
  107. const deferred = {};
  108. deferred.promise = new Promise(function (resolve, reject) {
  109. deferred.resolve = resolve
  110. deferred.reject = reject
  111. });
  112. sendQueue.push({
  113. url: requestContext.url,
  114. data: requestContext.data,
  115. deferred: deferred
  116. });
  117. if (wsClient && wsClient.readyState === WebSocket.OPEN) {
  118. fireSendQueue();
  119. }
  120. return deferred.promise;
  121. };
  122. let getReadyState = function () {
  123. if (!wsClient) {
  124. return null;
  125. }
  126. return wsClient.readyState;
  127. };
  128. module.exports = {
  129. init: init,
  130. connect: connect,
  131. reconnect: reconnect,
  132. send: send,
  133. getReadyState: getReadyState
  134. };