您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
jquery simple websocket
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyforks.org/scripts/407743/830687/jquery-simple-websocket.js
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * jQuery Simple Websocket * https://github.com/jbloemendal/jquery-simple-websocket */ (function (factory) { if ('object' === typeof module && typeof 'object' === module.exports) { module.exports = factory(jQuery); } else { factory(jQuery); } }(function($) { var SimpleWebSocket = function(opt) { if (this._isEmpty(opt, 'url')) { throw new Error('Missing argument, example usage: $.simpleWebSocket({ url: "ws://127.0.0.1:3000" }); '); } this._opt = opt; this._ws = null; this._reConnectTries = 60; this._reConnectDeferred = null; this._dataType = this._prop(this._opt, 'dataType', 'json'); this._listeners = []; var self = this; this._api = (function() { return { connect: function() { return $.extend(self._api, self._reConnect.apply(self, [])); }, isConnected: function(callback) { if (callback) { callback.apply(this, [self._isConnected.apply(self, [])]); return self._api; } else { return self._isConnected.apply(self, []); } }, send: function(data) { return $.extend(self._api, self._send.apply(self, [data])); }, listen: function(listener) { return $.extend(self._api, self._listenReconnect.apply(self, [listener])); }, remove: function(listener) { self._remove.apply(self, [listener]); return self._api; }, removeAll: function() { self._removeAll.apply(self, []); return self._api; }, close: function() { self._close.apply(self, []); self._reset.apply(self, []); return self._api; } }; })(); return this._api; }; SimpleWebSocket.prototype = { _createWebSocket: function(opt) { var ws = null; if (opt.protocols) { if ('undefined' === typeof window.MozWebSocket) { if (window.WebSocket) { ws = new WebSocket(opt.url, opt.protocols); } else { throw new Error('Error, websocket could not be initialized.'); } } else { ws = new MozWebSocket(opt.url, opt.protocols); } } else { if ('undefined' === typeof window.MozWebSocket) { if (window.WebSocket) { ws = new WebSocket(opt.url); } else { throw new Error('Error, websocket could not be initialized.'); } } else { ws = new MozWebSocket(opt.url); } } return ws; }, _bindSocketEvents: function(ws, opt) { var self = this; $(ws).bind('open', opt.open) .bind('close', opt.close) .bind('message', function(event) { try { if ('function' === typeof opt.message) { if (self._dataType && 'json' === self._dataType.toLowerCase()) { var json = JSON.parse(event.originalEvent.data); opt.message.call(this, json); } else if (self._dataType && 'xml' === self._dataType.toLowerCase()) { var domParser = new DOMParser(); var dom = domParser.parseFromString(event.originalEvent.data, 'text/xml'); opt.message.call(this, dom); } else { opt.message.call(this, event.originalEvent.data); } } } catch (exception) { if ('function' === typeof opt.error) { opt.error.call(this, exception); } } }).bind('error', function(exception) { if ('function' === typeof opt.error) { opt.error.call(this, exception); } }); }, _webSocket: function(opt) { var ws = this._createWebSocket(opt); this._bindSocketEvents(ws, opt); return ws; }, _getSocketEventHandler: function(attempt) { var self = this; return { open: function(e) { var sock = this; if (attempt) { attempt.resolve(sock); } }, close: function(e) { if (attempt) { attempt.rejectWith(e); } }, message: function(message) { for (var i=0, len=self._listeners.length; i<len; i++) { try { self._listeners[i].deferred.notify.apply(self, [message]); } catch (error) { } } }, error: function(e) { self._ws = null; for (var i=0, len=self._listeners.length; i<len; i++) { self._listeners[i].deferred.reject.apply(self, [e]); } if (attempt) { attempt.rejectWith.apply(self, [e]); } } }; }, _connect: function() { var attempt = $.Deferred(); if (this._ws) { if (2 === this._ws.readyState) { // close previous socket this._ws.close(); } else if (3 === this._ws.readyState) { // close previous socket this._ws.close(); } else if (0 === this._ws.readyState) { return attempt.promise(); } else if (1 === this._ws.readyState) { attempt.resolve(this._ws); return attempt.promise(); } } this._ws = this._webSocket($.extend(this._opt, this._getSocketEventHandler(attempt))); return attempt.promise(); }, _reset: function() { this._reConnectTries = this._prop(this._opt, 'attempts', 60); // default 10min this._reConnectDeferred = $.Deferred(); }, _close: function() { if (this._ws) { this._ws.close(); this._ws = null; } }, _isConnected: function() { if (null === this._ws) { return false; } else if (1 === this._ws.readyState) { return true; } return false; }, _reConnectTry: function() { var self = this; this._connect().done(function() { self._reConnectDeferred.resolve.apply(self, [self._ws]); }).fail(function(e) { self._reConnectTries--; if (self._reConnectTries > 0) { window.setTimeout(function() { self._reConnect.apply(self, []); }, self._prop.apply(self, [self._opt, 'timeout', 10000])); } else { self._reConnectDeferred.rejectWith.apply(self, [e]); } }); }, _reConnect: function() { var self = this; if (null === this._reConnectDeferred) { this._reset(); } else if ('resolved' === this._reConnectDeferred.state()) { this._reset(); } else if ('rejected' === this._reConnectDeferred.state()) { this._reset(); } if (this._ws && this._ws.readyState === 1) { this._reConnectDeferred.resolve(this._ws); } else { this._reConnectTry(); } return self._reConnectDeferred.promise.apply(self, []); }, _preparePayload: function(data) { var payload; if (this._opt.dataType && 'text' === this._opt.dataType.toLowerCase()) { payload = data; } else if (this._opt.dataType && 'xml' === this._opt.dataType.toLowerCase()) { payload = data; } else if (this._opt.dataType && 'json' === this._opt.dataType.toLowerCase()) { payload = JSON.stringify(data); } else { payload = JSON.stringify(data); // default } return payload; }, _send: function(data) { var self = this; var attempt = $.Deferred(); (function(json) { self._reConnect.apply(self, []).done(function(ws) { ws.send(json); attempt.resolve.apply(self, [self._api]); }).fail(function(e) { attempt.rejectWith.apply(self, [e]); }); })(this._preparePayload(data)); return attempt.promise(); }, _indexOfListener: function(listener) { for (var i=0, len=this._listeners.length; i<len; i++) { if (this._listeners[i].listener === listener) { return i; } } return -1; }, _isEmpty: function(obj, property) { if (typeof 'undefined' === obj) { return true; } else if (null === obj) { return true; } else if ('undefined' === typeof property) { return true; } else if (null === property) { return true; } else if ('' === property) { return true; } else if ('undefined' === typeof obj[property]) { return true; } else if (null === obj[property]) { return true; } return false; }, _prop: function(obj, property, defaultValue) { if (this._isEmpty(obj, property)) { return defaultValue; } return obj[property]; }, _listen: function(listener) { var self = this; var dInternal = $.Deferred(); self._reConnect.apply(self, []).done(function() { dInternal.progress(function() { listener.apply(this, arguments); }); self._remove.apply(self, [listener]); self._listeners.push({ 'deferred': dInternal, 'listener': listener }); }).fail(function(e) { dInternal.reject(e); }); return dInternal.promise(); }, _listenReconnect: function(listener) { var dExternal = $.Deferred(); var self = this; this._listen(listener) .fail(function() { dExternal.notify(arguments); self._listenReconnect.apply(self, [listener]); }).done(function() { dExternal.resolve(); }); return dExternal.promise(); }, _remove: function(listener) { var index = this._indexOfListener(listener); if (0 <= index) { this._listeners[index].deferred.resolve(); this._listeners.splice(index, 1); } }, _removeAll: function() { for (var i=0, len=this._listeners.length; i<len; i++) { this._listeners[i].deferred.resolve(); } this._listeners = []; } }; $.extend({ simpleWebSocket: function(opt) { return new SimpleWebSocket(opt); } }); return $.simpleWebSocket; }));