rpcForSvr.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. var io = require('socket.io-client');
  2. function rpcClient(url) {
  3. var param = {"reconnection":false,"force new connection":true};
  4. this.url = url;
  5. this.socket = io.connect(this.url, param);
  6. this.connect_count = 0;
  7. this.connect_cb = '';
  8. this.reconnect_cb = '';
  9. this.cid = 0;
  10. this.response_cb_map = {};
  11. this.static_cb_map = {};
  12. this.err_cb_map = {};
  13. this.BeatTimerId = -1;
  14. this.connect_status = "undefine";
  15. this.self_close = false;
  16. var that = this;
  17. var rpc_cli = this;
  18. this.copyAllListeners = function() {
  19. for (var key in that.static_cb_map) {
  20. var fn_list = that.static_cb_map[key];
  21. for(var cb_key in fn_list) {
  22. that.socket.on(key, fn_list[cb_key]);
  23. }
  24. }
  25. };
  26. this.reconnect = function() {
  27. if (that.self_close) return;
  28. if ("connected" == that.connect_status || "connecting" == that.connect_status) return;
  29. that.connect_status = "connecting";
  30. that.socket = io.connect(that.url, param);
  31. that.copyAllListeners();
  32. };
  33. this.clear_err_cb = function(reconnect_time) {
  34. that.response_cb_map = {} // rm all success cb
  35. for (var key in that.err_cb_map) {
  36. var err_cb = that.err_cb_map[key];
  37. err_cb(); // exe err cb
  38. }
  39. that.err_cb_map = {};
  40. };
  41. this.close = function() {
  42. that.self_close = true;
  43. that.socket.disconnect();
  44. that.clear_err_cb();
  45. that.socket.removeAllListeners();
  46. that.connect_status = "closed";
  47. };
  48. this.close_handler = function(reconnect_time) {
  49. that.socket.disconnect();
  50. that.clear_err_cb();
  51. that.socket.removeAllListeners();
  52. that.connect_status = "closed";
  53. reconnect_time = reconnect_time || 1000;
  54. setTimeout(function(){that.reconnect();},reconnect_time);
  55. };
  56. this.nextId = function() {
  57. var new_id = ++rpc_cli.cid;
  58. if (rpc_cli.cid > 999999999) {
  59. rpc_cli.cid = 0;
  60. }
  61. return new_id;
  62. };
  63. this.setBeatTime = function(beat_time, timeout) {
  64. if (that.BeatTimerId > 0) {
  65. clearInterval(that.BeatTimerId);
  66. that.BeatTimerId = -1;
  67. }
  68. if (beat_time <= 0) return;
  69. var timeout = timeout || 20000;
  70. that.BeatTimerId = setInterval(function(){
  71. if ("connected" == that.connect_status) {
  72. //console.log("rpc client send beat");
  73. that.emit('rpc_beat',"",{
  74. "success": function(){
  75. //console.log("rpc client beat suc");
  76. },
  77. "timeout_time": timeout,
  78. "timeout_cb": function(){
  79. console.log("client beat time out");
  80. that.socket.disconnect();
  81. },
  82. "error":function(){
  83. console.log("client beat error");
  84. }
  85. });
  86. }
  87. }, beat_time);
  88. };
  89. this.inner_on = function(route, cb) {
  90. var fn_list = that.static_cb_map[route] || new Array();
  91. fn_list.push(cb);
  92. that.static_cb_map[route] = fn_list;
  93. that.socket.on(route, function(data){
  94. cb(data);
  95. });
  96. }
  97. this.on = function(route, cb) {
  98. if ("connect" == route) {
  99. if (that.connect_status == "connected") cb();
  100. else that.connect_cb = cb;
  101. return;
  102. }
  103. if ("reconnect" == route) {
  104. that.reconnect_cb = cb;
  105. return;
  106. }
  107. that.inner_on(route, cb);
  108. };
  109. // rpc response
  110. this.on("rpc_response", function (data){
  111. if ("rpc_cid" in data && data.rpc_cid in that.response_cb_map) {
  112. var suc_cb = that.response_cb_map[data.rpc_cid];
  113. var suc_data = data.rpc_data || {};
  114. suc_cb(suc_data);
  115. }
  116. });
  117. // rpc request
  118. this.on("rpc_request", function (data){
  119. if (!("rpc_route" in data)) {
  120. return;
  121. }
  122. var rpc_route = data.rpc_route;
  123. if (!(rpc_route in that.static_cb_map)) {
  124. rpc_route = '*';
  125. }
  126. if (rpc_route in that.static_cb_map) {
  127. var fn_list = that.static_cb_map[rpc_route];
  128. for (var cb_key in fn_list) {
  129. var route_cb = fn_list[cb_key];
  130. var rpc_data = data.rpc_data || {};
  131. route_cb(rpc_data,function(response) {
  132. var response_json = {};
  133. response_json["rpc_cid"] = data.rpc_cid;
  134. response_json["rpc_data"] = response;
  135. that.socket.emit('rpc_response', response_json);
  136. });
  137. }
  138. }
  139. });
  140. // for beat
  141. this.on('rpc_beat', function (data, cb) {
  142. if (cb) cb("");
  143. });
  144. this.inner_on('connect',function(data){
  145. that.connect_status = "connected";
  146. that.connect_count += 1
  147. if (that.connect_count > 1) {
  148. if (typeof(that.reconnect_cb) == "function") that.reconnect_cb(data);
  149. } else {
  150. if (typeof(that.connect_cb) == "function") that.connect_cb(data);
  151. }
  152. });
  153. this.inner_on('reconnect',function(){
  154. that.connect_status = "connected";
  155. });
  156. this.on('disconnect', function(){that.close_handler(10);});
  157. this.on('connect_error', function(){that.close_handler(1000);});
  158. this.on('connect_timeout', function(){that.close_handler(1000);});
  159. //options:
  160. // success: callback for success response
  161. // error: callback for error
  162. // if has success callback:
  163. // timeout_time: time for timeout ms
  164. // timeout_cb: callback for timeout
  165. this.emit = function(route, msg, options) {
  166. options = options || {};
  167. //if (!options.success && !options.error) {// no callback
  168. if (false) {
  169. if (msg) {
  170. that.socket.emit(route,msg);
  171. } else {
  172. that.socket.emit(route);
  173. }
  174. } else {
  175. var new_id =String(that.nextId());
  176. var timeout_id;
  177. if (options.success) {
  178. // timeout callback
  179. if (options.timeout_cb) {
  180. var timeout = options.timeout_time || 10000;
  181. timeout_id = setTimeout(function() {
  182. if (new_id in that.err_cb_map) {delete that.err_cb_map[new_id];} // rm err cb
  183. if (new_id in that.response_cb_map) {
  184. delete that.response_cb_map[new_id]; // rm success cb
  185. options.timeout_cb(); // exe timeout cb
  186. }
  187. }, timeout);
  188. }
  189. // success callback
  190. var suc_cb_cb = function(suc_data) {
  191. if (new_id in that.response_cb_map) {delete that.response_cb_map[new_id];}
  192. if (new_id in that.err_cb_map) {delete that.err_cb_map[new_id];} // rm err cb
  193. if (timeout_id) {clearTimeout(timeout_id);} // rm timeout cb
  194. options.success(suc_data); // exe success cb
  195. };
  196. that.response_cb_map[new_id] = suc_cb_cb;
  197. }
  198. // err callback
  199. if (options.error) {
  200. var e_cb_cb = function() {
  201. if (new_id in that.response_cb_map) {delete that.response_cb_map[new_id];} // rm success cb
  202. if (timeout_id) {clearTimeout(timeout_id);} // rm timeout cb
  203. options.error(); // exe error cb
  204. }
  205. that.err_cb_map[new_id] = e_cb_cb;
  206. }
  207. if ("connected" != that.connect_status) {
  208. that.clear_err_cb();
  209. return;
  210. }
  211. var new_msg = {};
  212. new_msg["rpc_cid"] = new_id;
  213. new_msg["rpc_route"] = route;
  214. if (msg) {
  215. new_msg["rpc_data"] = msg;
  216. that.socket.emit("rpc_request",new_msg);
  217. } else {
  218. that.socket.emit("rpc_request",new_msg);
  219. }
  220. }
  221. };
  222. }
  223. module.exports = rpcClient;
  224. // $.ping = function(option)
  225. // {
  226. // var ping, requestTime, responseTime ;
  227. // var getUrl = function(url){ //保证url带http://
  228. // var strReg="^((https|http)?://){1}"
  229. // var re=new RegExp(strReg);
  230. // return re.test(url)?url:"http://"+url;
  231. // }
  232. // $.ajax({
  233. // url: getUrl(option.url)+'/'+ (new Date()).getTime() + '.html', //设置一个空的ajax请求
  234. // type: 'GET',
  235. // dataType: 'html',
  236. // timeout: option.timeout || 10000,
  237. // beforeSend : function()
  238. // {
  239. // if(option.beforePing) option.beforePing();
  240. // requestTime = new Date().getTime();
  241. // },
  242. // complete : function(XMLHttpRequest,status)
  243. // {
  244. // if(status=='success'){
  245. // responseTime = new Date().getTime();
  246. // ping = Math.abs(requestTime - responseTime);
  247. // if(option.afterPing) option.afterPing(ping);
  248. // } else {
  249. // if(option.error) option.error();
  250. // }
  251. // }
  252. // });
  253. // if(option.interval && option.interval > 0)
  254. // {
  255. // var interval = option.interval;
  256. // //setTimeout(function(){$.ping(option)}, interval);
  257. // // option.interval = 0; // 阻止多重循环
  258. // // setInterval(function(){$.ping(option)}, interval);
  259. // }
  260. // };