rpc.js 7.8 KB

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