晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/akaindir/www/crm/layouts/v7/lib/jquery/websockets/ |
Upload File : |
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* jquery.WebSocket
*
* jquery.WebSocket.js - enables WebSocket support with emulated fallback
*
* One simple interface $.WebSocket(url, protocol, options); thats it.
* The same interface as current native WebSocket implementation. The same
* native events (onopen, onmessage, onerror, onclose) + custom event onsend.
*
* But jquery.WebSockets adds some nice features:
*
* [x] Multiplexing - Use a single socket connection and as many logical pipes
* within as your browser supports. All these pipes are emulated WebSockets
* also with the same API + same events! Use each pipe as WebSocket! But
* this requires you to implement the protocol on this level of communication
* The data is en- + decoded in a special way to make multiplexing possible
*
* [x] Interface for adding protocol to manipulate data before they are send
* and right after they arrive before event onmessage is fired!
*
* LICENSE:
* jquery.WebSocket
*
* Copyright (c) 2012, Benjamin Carl - All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - All advertising materials mentioning features or use of this software
* must display the following acknowledgement: This product includes software
* developed by Benjamin Carl and other contributors.
* - Neither the name Benjamin Carl nor the names of other contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Please feel free to contact us via e-mail: opensource@clickalicious.de
*
* @category jquery
* @package jquery_plugin
* @subpackage jquery_plugin_WebSocket
* @author Benjamin Carl <opensource@clickalicious.de>
* @copyright 2012 - 2013 Benjamin Carl
* @license http://www.opensource.org/licenses/bsd-license.php The BSD License
* @version 0.0.3
* @link http://www.clickalicious.de
* @see -
* @since File available since Release 1.0.0
*/
(function($){
// attach to jQuery
$.extend({
// export WebSocket = $.WebSocket
WebSocket: function(url, protocol, options)
{
/**
* The default values, use comma to separate the settings,
* example:
*
* @type {jquery.WebSocket}
* @private
*/
var defaults = {
url: url,
http: null,
enableProtocols: false,
enablePipes: false,
encoding: 'utf-8', // fallback: encoding for AJAX LP
method: 'post', // fallback: method for AJAX LP
delay: 0, // number of ms to delay open event
interval: 3000 // number of ms between poll request
};
// overwrite (append) to option defaults
options = $.extend(
{},
defaults,
options
);
// WebSocket Id and readyStates
const WS_ID = 'WebSocketPipe';
const CONNECTING = 0;
const OPEN = 1;
const CLOSING = 2;
const CLOSED = 3;
// the function table to store references to callbacks
var _functionTable = {
onopen: function() {},
onerror: function(e) {},
onclose: function() {},
onmessage: function(e) {},
send: function(d) { _ws._send(d); }
};
/***********************************************************************************************************
*
* PRIVATE MEMBERS
*
**********************************************************************************************************/
/**
* private: _token
*
* Returns a random token on request
*
* This method is intend to return a random token on
* request e.g. used as pipe-Id
*
* @returns {String} Random token
*/
function _token()
{
return Math.random().toString(36).substr(2);
};
/**
* private: _urlWsToHttp
*
* Converts a ws:// or wss:// style link to a http:// or https:// link
*
* This method is intend to convert ws-links to http-links
*
* @returns {String} http-link
*/
function _urlWsToHttp(url)
{
var protocol = (url.attr('protocol') === 'wss') ? 'https://' : 'http://';
var host = url.attr('host');
var port = (
(url.attr('protocol') == 'wss' && url.attr('port') != 443) ||
(url.attr('protocol') == 'ws' && url.attr('port') != 80) ?
':' + url.attr('port') : ''
);
var path = ((url.attr('path') != '/') ? url.attr('path') : '');
// return new combined url
return protocol + host + port + path;
};
/**
* private: _dispatchProtocol
*
* Dispatch event to registered protocol handler
* (events: onmessage, onsend[only on emulated WebSocket!])
*
* @param e The event object
*
* @returns The processed object
*/
function _dispatchProtocol(e, direction, ws)
{
// give object event from protocol to protocol
for (var protocol in ws.protocols) {
e = ws.protocols[protocol].callback(e, direction);
}
// return dirty object
return e;
};
/**
* private: _dispatchPipe
*
* Dispatch event to pipe
* (events: onmessage, onsend)
*/
function _dispatchPipe(id, e)
{
for (var pipe in ws.pipes) {
if (pipe == id) {
var p = ws.pipes[pipe];
if (p.onmessage !== undefined &&
typeof(p.onmessage) === 'function'
) {
p.onmessage(e);
}
}
}
};
/**
* private: _proxy
*
* This is the proxy between an intercepted call and calls
* the user defined callback
*
* @param {String} trigger The trigger (event-name) to dispatch
* @param {Object} e The event object to dispatch
*
* @returns The result of dispatch (depends on operation!)
* @private
*/
function _proxy(trigger, e)
{
return _functionTable[trigger](e);
};
/**
* private: _injectHook
*
* Injects hooks into a given WebSocket object
*
* This method injects the hooks for the given name of an event (event)
* into a given WebSocket object (ws).
*
* @param {String} event The name of the event to hook
* @param {Object} ws An instance of a WebSocket to patch (inject to)
*
* @returns void
* @private
*/
function _injectHook(event, ws)
{
//
if (event == 'send') {
ws._send = ws.send;
}
// install our proxy method for intercepting events
ws[event] = function(e) {
var uid;
if (event == 'onmessage') {
// apply registered protocols first
e = _dispatchProtocol(e, 'i', ws);
// where to get info -> multiplexed?
// if multiplexed look into package for uid
if (ws.multiplexed) {
// extract uid
uid = /"uid"\:\s"([a-z0-9A-z]*)"/.exec(e.data)[1];
}
if (uid !== undefined) {
$(ws.pipes[uid]).trigger(e);
} else {
// dispatch to all pipes
for (pipe in ws.pipes) {
$(ws.pipes[pipe]).trigger(
e
);
}
}
}
(event == 'send') ? e = _dispatchProtocol(e, 'o', ws) : null;
_proxy(event, e);
};
// override setter with custom hook to fetch user defined callbacks
window.WebSocket.prototype.__defineSetter__(
event,
function(v) {
_functionTable[event] = v;
}
);
// override getter with custom hook to fetch user defined callbacks
window.WebSocket.prototype.__defineGetter__(
event,
function() {
return _functionTable[event];
}
);
};
/**
* Returns a fresh pipe-object, which is in fact an emulated WebSocket
* which is extended here within on the fly with our pipe logic.
*
* @param {String} url The url connect to (resource or path ...)
* @param {String} id The optional Id of the pipe (unique-identifier)
*
* @returns {Object} A fresh pipe (emulated WebSocket)
* @private
*/
function _protocol(name, callback)
{
return {
name: name,
callback: callback
};
};
/**
* Returns a fresh pipe-object, which is in fact an emulated WebSocket
* which is extended here within on the fly with our pipe logic.
*
* @param {String} url The url connect to (resource or path ...)
* @param {String} id The optional Id of the pipe (unique-identifier)
*
* @returns {Object} A fresh pipe (emulated WebSocket)
* @private
*/
function _pipe(url)
{
// create, merge and return new pipe instance
return $.extend(
_getWebSocketSkeleton(url, false), // merge an websocket structure _getWebSocketSkeleton(url)
{ // with our additions {}
packet: function(uid) {
return {
type: WS_ID,
action: 'message',
data: null,
uid: uid
};
},
startup: function() {
var p = this.packet(this.uid, this.url);
p.action = 'startup';
p.data = this.url;
_ws.send(
JSON.stringify(p)
);
},
shutdown: function() {
// send shutdown pipe packet
var p = this.packet(this.uid, this.url);
p.action = 'shutdown';
// send as text string
_ws.send(
JSON.stringify(p)
);
},
send: function(data) {
// get packet
var p = this.packet(this.uid, this.url);
p.data = data;
// send as text string
_ws.send(
JSON.stringify(p)
);
// trigger event send
$(this).triggerHandler('send');
},
start: function() {
// send initial packet to server for handshaking
this.startup();
// trigger event open
$(this).triggerHandler('open');
return this;
},
close: function() {
// send packet close
this.shutdown();
// trigger native event WebSocket:onclose (native)
$(this).triggerHandler('close');
}
}
);
}
/**
* Returns skeleton of a WebSocket object
*
* @param {String} url The url connect to (resource or path ...)
* @param {String} id The optional Id of the pipe (unique-identifier)
*
* @returns {Object} A fresh pipe (emulated WebSocket)
* @private
*/
function _getWebSocketSkeleton(url, isNative)
{
return {
type: 'WebSocket', // CUSTOM type String type of object
uid: _token(), // CUSTOM uid an unique Id used to identify the ws
//native: isNative, // CUSTOM native status as boolean
readyState: CONNECTING, // NATIVE default status is 0 = CONNECTING
bufferedAmount: 0, // NATIVE integer currently buffered data in bytes
url: url, // NATIVE url The url to connect to
send: function(data) {}, // NATIVE send() sending "data" to server
start: function() {}, // CUSTOM start() used as custom trigger for opening
close: function() {}, // NATIVE close() closes the connection
onopen: function() {}, // NATIVE EVENT
onerror: function(e) {}, // NATIVE EVENT
onclose: function() {}, // NATIVE EVENT
onmessage: function(e) {}, // NATIVE EVENT
protocols: {}, // CUSTOM container for protocols in user defined order
pipes: {}, // CUSTOM container for all registered pipes
multiplexed: false, // CUSTOM multiplexed status of this object
/**
* Export: registerPipe()
*
* Creates a new pipe and return pipe-reference.
*
* This method creates a "pipe" which is in fact an emulated WebSocket
* (the same emulation as used in older browsers). These "pipes" are
* used as a logical connection within a physical connection to the Server
*
* Pipe 1 -> O==\ (WebSocket) /==O -> Pipe 1
* Pipe 2 -> O==========================O -> Pipe 2
* Pipe 3 -> O==/ \==O -> Pipe 3
*
* So we can use those Pipes in the same way like the original WebSocket object.
* You can use the same events what enables you and your app to use less
* connections between server and client and use different endpoints for your
* services too.
*
* @param {String} url The url to connect to
* @param {String} protocol The protocol to use
* @param {Object} options Custom options to pass through
*
* @returns {Object} the instance created
*/
registerPipe: function(url, protocol, options) {
var p = new _pipe(url);
this.multiplexed = true;
// we iterate the functionTable and use the events for injecting our hooks
for (event in _functionTable) {
// inject all hooks except "send"
if (event != 'send') {
_injectHook(event, p);
}
}
// try:
// return ws.pipes[p.id] = p = new _pipe(url, id);
var r = this.pipes[p.uid] = $.extend(p, options).start();
return r;
},
unregisterPipe: function(id) {
this.pipes[id] = null;
(this.pipes.length === 0) ? this.multiplexed = false : void(0);
// timer?
},
registerProtocol: function(name, callback) {
var p = new _protocol(name, callback);
return this.protocols[name] = p;
},
unregisterProtocol: function(name) {
this.protocols[name] = null;
},
extension: null,
protocol: null,
reason: null,
binaryType: null
};
}
/**
* Creates and return a new jQuery error event with passed var added as .data
*
* @param {Mixed} data The data to add to event
*
* @returns {jQuery.Event} An jQuery error event object
* @private
*/
function _ErrorEvent(data)
{
// create MessageEvent event and add received data
var e = jQuery.Event('error');
e.data = data;
return e;
}
/**
* Creates and return a new jQuery message event with passed var added as .data
*
* @param {Mixed} data The data to add to event
*
* @returns {jQuery.Event} An jQuery message event object
* @private
*/
function _MessageEvent(data)
{
// create MessageEvent event and add received data
var e = jQuery.Event('message');
e.data = data;
return e;
}
/**
* Returns an emulated WebSocket which is build upon jQueries AJAX functionality.
*
* @param {Mixed} data The data to add to event
*
* we create and return an emulated WebSocket Object. We you can use this object in a very
* similar way to the native WebSocket Implementation. The connection was graceful degraded to
* AJAX long polling ...
*
* @returns ???
* @private
*/
function _WebSocket(url)
{
var _interval, _handler, _emulation = {
/**
* export: send
*
* Sends data via options.method to server (http/xhr request)
*
* This method is intend to ...
*
* @param mixed data The data to send
*
* @returns boolean TRUE on success, otherwise FALSE
*/
send: function(data) {
// default result is true = success
var success = true;
// send data via jQuery ajax()
$.ajax({
async: false,
type: options.method,
url: url + (
(options.method == 'GET' && options.arguments) ?
'?' + $.param(options.arguments) :
''
),
data: (
(options.method == 'POST' && options.arguments) ?
$.param($.extend(options.arguments, {data: data})) :
null
),
dataType: 'text',
contentType: "application/x-www-form-urlencoded; charset=" + options.encoding,
success: function(data) {
// trigger native event MessageEvent (emulated)
$(_emulation).trigger(
new _MessageEvent(_dispatchProtocol(data, 'i', _emulation))
);
},
error: function(xhr, data, errorThrown) {
// in case of error no success
success = false;
// trigger native event ErrorEvent (emulated)
$(_emulation).trigger(
_ErrorEvent(data)
);
}
});
// return result of operation
return success;
},
/**
* export: close
*
* Closes an existing and open connection
*
* This method is intend to ...
*
* @returns void
*/
close: function() {
// kill timer!
clearTimeout(_handler);
clearInterval(_interval);
// update readyState
this.readyState = CLOSED;
// trigger native event WebSocket:onclose (native)
$(_emulation).triggerHandler('close');
}
};
/**
* private: _poll
*
* Polls server for new data and returns the result
*
* This method is intend to ...
*
* @returns void
* @private
*/
function _poll() {
$.ajax({
type: options.method,
url: url + (
(options.method == 'GET' && options.arguments) ?
'?' + $.param(options.arguments) :
''
),
dataType: 'text',
data: (
(options.method == 'POST' && options.arguments) ?
$.param(options.arguments) :
null
),
success: function(data) {
// trigger our emulated MessageEvent
$(_emulation).trigger(
new _MessageEvent(data)
);
},
error: function(xhr, data, errorThrown) {
// in case of error no success
success = false;
// trigger native event ErrorEvent (emulated)
$(_emulation).trigger(
_ErrorEvent(data)
);
}
});
// trigger custom event WebSocket:onsend (custom)
$(_emulation).triggerHandler('send');
};
// run our emulation
_handler = setTimeout(
function() {
_emulation.readyState = OPEN;
_poll();
_interval = setInterval(_poll, options.interval);
// trigger event WebSocket:onopen (emulated)
$(_emulation).triggerHandler('open');
},
options.delay
);
// return emulated socket implementation
return _emulation;
};
/**
* private: _extend
*
* Copies all properties from source to destination object as
* long as they not exist in destination.
*
* This method is intend to ...
*
* @param {Object} source The object to copy from
* @param {Object} destination The object to copy to
*
* @returns {Object} The object destination with new properties set
* @private
*/
function _extend(source, destination) {
for (property in source) {
if (!destination[property]) {
destination[property] = source[property];
}
}
return destination;
}
/**
* private: _getWebSocket
*
* Returns a WebSocket-Object (native or emulated)
*
* This method is intend to return a WebSocket-Object no matter
* if the browser supports native WebSockets or not. For older
* Browsers the WebSocket-Object is emulated with Ajax (Fake)
* Push: Long Polling.
*
* @param {String} url The resource-locator (e.g. ws://127.0.0.1:80/ ||
* ws://127.0.0.1:80/this/is/fallback/)
*
* @returns {Object} WebSocket
* @private
*/
function _getWebSocket(url)
{
var ws, isNative = true;
// websocket support built in?
if (window.WebSocket) {
// in firefox we use MozWebSocket (but it seems that from now (FF 17) MozWebsocket is removed)
if (typeof(MozWebSocket) == 'function') {
ws = new MozWebSocket(url);
} else {
ws = new WebSocket(url);
}
} else {
// inject emulated WebSocket implementation into DOM
window.WebSocket = _WebSocket;
url = options.http;
isNative = false;
ws = new WebSocket(url);
}
// extend it with our additions and return
return _extend(
_getWebSocketSkeleton(url, isNative),
ws
);
};
/***********************************************************************************************************
*
* MAIN()
*
**********************************************************************************************************/
// get WebSocket object (either native or emulated)
var _ws = _getWebSocket(options.url);
// we iterate the functionTable and use the events for injecting our hooks
for (event in _functionTable) {
_injectHook(event, _ws);
}
// return WebSocket
return _ws;
}
});
})(jQuery);