ws_sdk.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. (function (WINDOW) {
  2. WINDOW.WS_SDK = function (url,msgCallBackFunc,isReconnect) {
  3. if (!window.WebSocket) {
  4. window.WebSocket = window.MozWebSocket;
  5. }
  6. if (!window.WebSocket) {
  7. alert("抱歉,您的浏览器不支持WebSocket协议!");
  8. return;
  9. }
  10. if (WS_SDK._CONS_ && WS_SDK._CONS_.WEB_SOCKET && url == WS_SDK._CONS_.URL) {
  11. WS_SDK.close();
  12. }
  13. WS_SDK._init_(url,msgCallBackFunc,isReconnect);
  14. WS_SDK.initWebSocket();
  15. WS_SDK.self = this;
  16. };
  17. WS_SDK.self = {};
  18. var configure = {
  19. heartbeatTimer:1500, //心跳定时器
  20. timeoutTimer:null, //超时定时器
  21. heartbeatMS:3000, //心跳时间
  22. timeoutMS:30000, //超时时间
  23. reconnectNum:0, //重连次数
  24. reconnectMaxNum:20, //最大重连次数
  25. reconnectMS:1000, //重连 毫秒 (梯度)
  26. allowAccess:true //是否允许访问
  27. };
  28. WS_SDK._init_ = function (url,msgCallBackFunc,isReconnect) {
  29. this._CONS_={
  30. URL : url, //socket 服务器地址
  31. WEB_SOCKET:null, //websocket 对象
  32. msgCallBackFunc:msgCallBackFunc,
  33. isReconnect:isReconnect?isReconnect:true, //是否自动重连
  34. EVENT_TYPE:{ //事件类型
  35. open :"open", //通道打开
  36. message: "message", //服务端消息接收
  37. close: "close", //通道关闭
  38. error: "error" //消息异常
  39. }
  40. }
  41. };
  42. WS_SDK.handle= function (eventType,event,msg) {
  43. try {
  44. this._CONS_.handleFunc(eventType,event,msg);
  45. } catch (e) {
  46. console.error("业务处理回调方法异常:");
  47. console.error(e);
  48. }
  49. },
  50. WS_SDK.ping =function(){
  51. var imdata = new proto.IMData();
  52. imdata.setType(4);
  53. imdata.setTimestamp(new Date().getTime());
  54. if(WS_SDK._CONS_.WEB_SOCKET.readyState===1 || WS_SDK._CONS_.WEB_SOCKET.readyState == WebSocket.OPEN){
  55. WS_SDK._CONS_.WEB_SOCKET.send(imdata.serializeBinary());
  56. }else{
  57. console.error("ping fail");
  58. }
  59. setTimeout("WS_SDK.ping()",configure.heartbeatMS);
  60. }
  61. WS_SDK.initWebSocket = function () {
  62. var self = this;
  63. //重连
  64. function reconnect () {
  65. WS_SDK._CONS_.WEB_SOCKET.close();
  66. if (self._CONS_.isReconnect) {
  67. connect();
  68. configure.timeoutTimer = null;
  69. }
  70. console.debug("重连--------------");
  71. console.debug(configure);
  72. console.debug("重连--------------");
  73. }
  74. //设置长时间无通信处理定时器
  75. function setTimeoutTimer(timerTime) {
  76. if (configure.timeoutTimer) {
  77. clearTimeout(configure.timeoutTimer);
  78. }
  79. configure.timeoutTimer = setTimeout(function (){
  80. configure.timeoutTimer = null;
  81. reconnect();
  82. },timerTime);
  83. }
  84. //设置心跳定时器
  85. function setTeartbeatTimer () {
  86. setTimeout("WS_SDK.ping()",configure.heartbeatMS);
  87. }
  88. //异常重连
  89. function errorReconnect() {
  90. if (!configure.timeoutTimer) {
  91. if (configure.reconnectNum < configure.reconnectMaxNum) {
  92. configure.reconnectNum = configure.reconnectNum + 1;
  93. configure.timeoutTimer = setTimeoutTimer(configure.reconnectMS);
  94. } else {
  95. console.error("无法连接请稍后再试");
  96. }
  97. }
  98. }
  99. //连接
  100. function connect() {
  101. if('WebSocket' in window){
  102. self._CONS_.WEB_SOCKET=new WebSocket(self._CONS_.URL);
  103. }else if ('MozWebSocket' in window){
  104. self._CONS_.WEB_SOCKET = new MozWebSocket(self._CONS_.URL);
  105. }
  106. //消息接收监听
  107. WS_SDK._CONS_.WEB_SOCKET.onmessage = function (event) {
  108. var reader = new FileReader();
  109. reader.readAsArrayBuffer(event.data);
  110. reader.onload = function (e) {
  111. var buf = new Uint8Array(reader.result);
  112. var imData = proto.IMData.deserializeBinary(buf);
  113. if(imData==undefined){
  114. console.info("错误的消息");
  115. }
  116. if(imData.getType() === 4){
  117. console.info("收到心跳响应");
  118. return;
  119. }
  120. if(imData.getType() === 1){
  121. var initData = imData.getInitdata();
  122. configure.allowAccess = initData.getAllowaccess();
  123. if (!configure.allowAccess) {
  124. WS_SDK._CONS_.WEB_SOCKET.close();
  125. console.info("非法连接!!!");
  126. return;
  127. }
  128. configure.heartbeatMS = initData.getHeartbeatms();
  129. configure.timeoutMS = initData.getTimeoutms();
  130. configure.reconnectMaxNum = initData.getReconnectmaxnum();
  131. configure.reconnectMS = initData.getReconnectms();
  132. setTeartbeatTimer ();
  133. return;
  134. }
  135. //TODO 消息防丢处理
  136. if(imData.getType() === 3){
  137. return;
  138. }
  139. if(imData.getType() === 2){
  140. WS_SDK._CONS_.msgCallBackFunc(imData.getMsgdata());
  141. var imdataResponse = new proto.IMData();
  142. imdataResponse.setId(imData.getId());
  143. imdataResponse.setType(3);
  144. WS_SDK._CONS_.WEB_SOCKET.send(imdataResponse.serializeBinary());
  145. }
  146. }
  147. };
  148. //通道开启事件
  149. WS_SDK._CONS_.WEB_SOCKET.onopen = function (event) {
  150. console.debug("开启--------------");
  151. console.debug(configure);
  152. console.debug(event);
  153. console.debug("开启--------------");
  154. };
  155. //关闭事件
  156. WS_SDK._CONS_.WEB_SOCKET.onclose = function (event) {
  157. console.debug("关闭--------------");
  158. clearTimeout(configure.heartbeatTimer);
  159. if (configure.allowAccess) {
  160. errorReconnect();
  161. }
  162. };
  163. //异常事件
  164. WS_SDK._CONS_.WEB_SOCKET.error = function (event) {
  165. if (configure.allowAccess) {
  166. errorReconnect();
  167. }
  168. }
  169. };
  170. connect();
  171. }
  172. WS_SDK.prototype = {
  173. close : function () {
  174. console.info("============")
  175. clearTimeout(configure.timeoutTimer);
  176. configure.timeoutTimer= null;
  177. clearTimeout(configure.heartbeatTimer);
  178. configure.heartbeatTimer= null;
  179. WS_SDK._CONS_.WEB_SOCKET.close();
  180. },
  181. send :function (sysId,toUserId,sType,msgType,msg,customType) { //发送消息
  182. if (WS_SDK._CONS_.WEB_SOCKET.readyState ===1 || WS_SDK._CONS_.WEB_SOCKET.readyState == WebSocket.OPEN) {
  183. try {
  184. var imdata = new proto.IMData();
  185. imdata.setId(new Date().getTime());
  186. imdata.setType(2);
  187. imdata.setTimestamp(new Date().getTime());
  188. var msgData = new proto.IMData.MsgData();
  189. if(sysId!=undefined&&sysId!="") {
  190. msgData.setSysid(Long.fromValue(sysId, false));
  191. }
  192. var fromData = new proto.IMData.MsgData.FromUser();
  193. fromData.setId(Long.fromValue(WS_SDK._CONS_.imUid,false));
  194. if(sysId!=undefined&&sysId!=""){
  195. fromData.setSysid(Long.fromValue(sysId,false));
  196. }
  197. fromData.setBususerid(WS_SDK._BUSUSERINFO_.busUid);
  198. fromData.setHeadimg(WS_SDK._BUSUSERINFO_.headImg);
  199. fromData.setNickname(WS_SDK._BUSUSERINFO_.nickName);
  200. msgData.setFromuser(fromData);
  201. msgData.setMsgbody(msg);
  202. msgData.setMsgtype(msgType);
  203. if(msgType!=undefined&&msgType=='custom'){
  204. if(customType==undefined||customType==''){
  205. alert("自定义消息中自定义类型不能为空自定义类型不能为空")
  206. return;
  207. }
  208. msgData.setCustomtype(customType);
  209. }
  210. msgData.setStype(sType);
  211. msgData.setTouserid(Long.fromValue(toUserId,false));
  212. msgData.setSendtime(new Date().getTime());
  213. imdata.setMsgdata(msgData);
  214. WS_SDK._CONS_.WEB_SOCKET.send(imdata.serializeBinary());
  215. return true;
  216. } catch (e){
  217. console.error(e);
  218. console.error("网络异常,请稍后再试!!!");
  219. return false;
  220. }
  221. } else {
  222. console.error("网络异常,请稍后再试!!!");
  223. WS_SDK._CONS_.WEB_SOCKET.error("");
  224. return false;
  225. }
  226. }
  227. }
  228. })(window);