| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /**
- *
- * MDN文档参考:https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
- */
- ;(function(root, factory){
- var ws = factory(root);
- if(typeof define === 'function' && define.amd){
- define([],factory);
- }else if(typeof module !== 'undefined' &&module.exports){
- module.exports=factory();
- }else{
- root.ws = factory();
- }
- }(this, function(root, undefined){
- if(!('WebSocket' in window)) return;
- var _handlers = {},wsocket,
- eventTarget = document.createElement('div'),
- settings = {
- //是否自动重连
- automaticOpen: true,
- //自动重连延迟重连速度速度
- reconnectDecay: 1.5
- },
- func = function () {},
- //对外泄露 API 😄
- _api = {
- CONNECTING: WebSocket.CONNECTING,
- OPEN: WebSocket.OPEN,
- CLOSING: WebSocket.CLOSING,
- CLOSED: WebSocket.CLOSED
- };
- /**
- * [ws]
- * @param 参数 url 为建立连接的URL
- * @param 参数 protocols 为服务器选择的子协定
- * @param 参数 options 初始化定义参数
- */
- function ws(url, protocols, options){
- var self = this;
- //websocket url
- this.url = url;
- //websocket 状态
- this.readyState = WebSocket.CONNECTING;
- /**
- * http://tools.ietf.org/html/rfc6455
- * 服务器选择的子协定,这是建立 WebSocket 对象时 protocols 参数里的其中一个字符串。
- */
- this.protocol = protocols ? protocols : null;
- // 绑定选项定义设置
- if (!options) {options = {};}
- for (var key in settings) {
- if (typeof options[key] !== 'undefined') this[key] = options[key];
- else this[key] = settings[key];
- }
- // 公开 API
- for(var a in _api) this[a] = _api[a];
-
- //用事件处理程序
- eventTarget.addEventListener('open', function(event) {self!==window&&self.onopen(event); });
- eventTarget.addEventListener('close', function(event) {self!==window&&self.onclose(event); });
- eventTarget.addEventListener('connecting', function(event) {self!==window&&self.onconnecting(event); });
- eventTarget.addEventListener('message', function(event) {self!==window&&self.onmessage(event); });
- eventTarget.addEventListener('error', function(event) {self!==window&&self.onerror(event); });
- // 公开事件目标的API
- this.addEventListener = eventTarget.addEventListener.bind(eventTarget);
- this.removeEventListener = eventTarget.removeEventListener.bind(eventTarget);
- this.dispatchEvent = eventTarget.dispatchEvent.bind(eventTarget);
- if(this.automaticOpen === true&&this!==window) this.open();
- return this;
- }
- /**
- * [generateEvent 该函数产生一个事件,与标准兼容,兼容的浏览器和IE9 - IE11?]
- * http://stackoverflow.com/questions/19345392/why-arent-my-parameters-getting-passed-through-to-a-dispatched-event/19345563#19345563
- * https://msdn.microsoft.com/library/ff975299(v=vs.85).aspx
- * @param eventName 位字符串类型的事件名字
- * @param 参数的args对象的可选对象,该事件将使用
- */
- function generateEvent(eventName, args) {
- var evt = document.createEvent("CustomEvent");
- evt.initCustomEvent(eventName, false, false, args);
- return evt;
- }
- ws.prototype.onconnecting = func;
- ws.prototype.onerror = func;
- ws.prototype.onopen = func;
- ws.prototype.onmessage = func;
- /**
- * [send 发送 websocket 消息]
- * @param 参数 data 为发消息的内容
- */
- ws.prototype.send = function (data) {
- if(this.wsocket) this.wsocket.send(data);
- else{
- throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';
- }
- };
- /**
- * [close 关闭 websocket 连接。]
- * 如果已经关闭了连接,此方法不起作用。
- *
- * 错误代码参考:https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
- * @param 参数 code 为错误代码 1000为正常关闭
- * @param 参数 reason 为错误理由
- */
- ws.prototype.close = function (code, reason){
- // 默认CLOSE_NORMAL代码
- if (typeof code === 'undefined') code = 1000;
- if (this.wsocket) this.wsocket.close(code, reason);
- };
- /**
- * [open 打开建立 websocket 握手连接]
- */
- ws.prototype.open = function () {
- var self = this;
- wsocket = new WebSocket(this.url, this.protocol || []);
- eventTarget.dispatchEvent(generateEvent('connecting'));
- wsocket.onopen = function(event) {
- self.protocol = ws.protocol;
- self.readyState = WebSocket.OPEN;
- var e = generateEvent('open');
- eventTarget.dispatchEvent(e);
- };
- wsocket.onclose = function(event) {
- self.readyState = WebSocket.CLOSED;
- var e = generateEvent('connecting');
- e.code = event.code;
- e.reason = event.reason;
- e.wasClean = event.wasClean;
- eventTarget.dispatchEvent(e);
- eventTarget.dispatchEvent(generateEvent('close'));
- };
- wsocket.onmessage = function(event) {
- var e = generateEvent('message');
- e.data = event.data;
- eventTarget.dispatchEvent(e);
- };
- wsocket.onerror = function(event) {
- var e = generateEvent('error');
- eventTarget.dispatchEvent(e);
- };
- this.wsocket = wsocket;
- return this;
- };
- return ws;
- }));
|