Update websock.js from noVNC
Sync with noVNC as of commit ae510306b5094b55aa08a2a0d15a151704f70993. The main change is to make it a more proper object that you can instantiate multiple times.
This commit is contained in:
parent
10e13d7a7e
commit
3f8f301d7f
|
@ -13,288 +13,355 @@
|
||||||
* read binary data off of the receive queue.
|
* read binary data off of the receive queue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*jslint browser: true, bitwise: false, plusplus: false */
|
/* [module]
|
||||||
/*global Util */
|
* import Util from "./util";
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*jslint browser: true, bitwise: true */
|
||||||
|
/*global Util*/
|
||||||
|
|
||||||
function Websock() {
|
/* [module] export default */ function Websock() {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var api = {}, // Public API
|
this._websocket = null; // WebSocket object
|
||||||
websocket = null, // WebSocket object
|
|
||||||
rQ = [], // Receive queue
|
|
||||||
rQi = 0, // Receive queue index
|
|
||||||
rQmax = 10000, // Max receive queue size before compacting
|
|
||||||
sQ = [], // Send queue
|
|
||||||
|
|
||||||
eventHandlers = {
|
this._rQi = 0; // Receive queue index
|
||||||
'message' : function() {},
|
this._rQlen = 0; // Next write position in the receive queue
|
||||||
'open' : function() {},
|
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
||||||
'close' : function() {},
|
this._rQmax = this._rQbufferSize / 8;
|
||||||
'error' : function() {}
|
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
},
|
this._rQ = null; // Receive queue
|
||||||
|
|
||||||
test_mode = false;
|
this._sQbufferSize = 1024 * 10; // 10 KiB
|
||||||
|
// called in init: this._sQ = new Uint8Array(this._sQbufferSize);
|
||||||
|
this._sQlen = 0;
|
||||||
|
this._sQ = null; // Send queue
|
||||||
|
|
||||||
|
this.maxBufferedAmount = 200;
|
||||||
|
|
||||||
//
|
this._eventHandlers = {
|
||||||
// Queue public functions
|
'message': function () {},
|
||||||
//
|
'open': function () {},
|
||||||
|
'close': function () {},
|
||||||
|
'error': function () {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
function get_sQ() {
|
(function () {
|
||||||
return sQ;
|
"use strict";
|
||||||
}
|
// this has performance issues in some versions Chromium, and
|
||||||
|
// doesn't gain a tremendous amount of performance increase in Firefox
|
||||||
|
// at the moment. It may be valuable to turn it on in the future.
|
||||||
|
var ENABLE_COPYWITHIN = false;
|
||||||
|
|
||||||
function get_rQ() {
|
var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
|
||||||
return rQ;
|
|
||||||
}
|
|
||||||
function get_rQi() {
|
|
||||||
return rQi;
|
|
||||||
}
|
|
||||||
function set_rQi(val) {
|
|
||||||
rQi = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
function rQlen() {
|
var typedArrayToString = (function () {
|
||||||
return rQ.length - rQi;
|
// This is only for PhantomJS, which doesn't like apply-ing
|
||||||
}
|
// with Typed Arrays
|
||||||
|
try {
|
||||||
|
var arr = new Uint8Array([1, 2, 3]);
|
||||||
|
String.fromCharCode.apply(null, arr);
|
||||||
|
return function (a) { return String.fromCharCode.apply(null, a); };
|
||||||
|
} catch (ex) {
|
||||||
|
return function (a) {
|
||||||
|
return String.fromCharCode.apply(
|
||||||
|
null, Array.prototype.slice.call(a));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
function rQpeek8() {
|
Websock.prototype = {
|
||||||
return (rQ[rQi] );
|
// Getters and Setters
|
||||||
}
|
get_sQ: function () {
|
||||||
function rQshift8() {
|
return this._sQ;
|
||||||
return (rQ[rQi++] );
|
},
|
||||||
}
|
|
||||||
function rQunshift8(num) {
|
|
||||||
if (rQi === 0) {
|
|
||||||
rQ.unshift(num);
|
|
||||||
} else {
|
|
||||||
rQi -= 1;
|
|
||||||
rQ[rQi] = num;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
get_rQ: function () {
|
||||||
function rQshift16() {
|
return this._rQ;
|
||||||
return (rQ[rQi++] << 8) +
|
},
|
||||||
(rQ[rQi++] );
|
|
||||||
}
|
|
||||||
function rQshift32() {
|
|
||||||
return (rQ[rQi++] << 24) +
|
|
||||||
(rQ[rQi++] << 16) +
|
|
||||||
(rQ[rQi++] << 8) +
|
|
||||||
(rQ[rQi++] );
|
|
||||||
}
|
|
||||||
function rQshiftStr(len) {
|
|
||||||
if (typeof(len) === 'undefined') { len = rQlen(); }
|
|
||||||
var arr = rQ.slice(rQi, rQi + len);
|
|
||||||
rQi += len;
|
|
||||||
return String.fromCharCode.apply(null, arr);
|
|
||||||
}
|
|
||||||
function rQshiftBytes(len) {
|
|
||||||
if (typeof(len) === 'undefined') { len = rQlen(); }
|
|
||||||
rQi += len;
|
|
||||||
return rQ.slice(rQi-len, rQi);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rQslice(start, end) {
|
get_rQi: function () {
|
||||||
if (end) {
|
return this._rQi;
|
||||||
return rQ.slice(rQi + start, rQi + end);
|
},
|
||||||
} else {
|
|
||||||
return rQ.slice(rQi + start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
|
set_rQi: function (val) {
|
||||||
// to be available in the receive queue. Return true if we need to
|
this._rQi = val;
|
||||||
// wait (and possibly print a debug message), otherwise false.
|
},
|
||||||
function rQwait(msg, num, goback) {
|
|
||||||
var rQlen = rQ.length - rQi; // Skip rQlen() function call
|
// Receive Queue
|
||||||
if (rQlen < num) {
|
rQlen: function () {
|
||||||
if (goback) {
|
return this._rQlen - this._rQi;
|
||||||
if (rQi < goback) {
|
},
|
||||||
throw("rQwait cannot backup " + goback + " bytes");
|
|
||||||
|
rQpeek8: function () {
|
||||||
|
return this._rQ[this._rQi];
|
||||||
|
},
|
||||||
|
|
||||||
|
rQshift8: function () {
|
||||||
|
return this._rQ[this._rQi++];
|
||||||
|
},
|
||||||
|
|
||||||
|
rQskip8: function () {
|
||||||
|
this._rQi++;
|
||||||
|
},
|
||||||
|
|
||||||
|
rQskipBytes: function (num) {
|
||||||
|
this._rQi += num;
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO(directxman12): test performance with these vs a DataView
|
||||||
|
rQshift16: function () {
|
||||||
|
return (this._rQ[this._rQi++] << 8) +
|
||||||
|
this._rQ[this._rQi++];
|
||||||
|
},
|
||||||
|
|
||||||
|
rQshift32: function () {
|
||||||
|
return (this._rQ[this._rQi++] << 24) +
|
||||||
|
(this._rQ[this._rQi++] << 16) +
|
||||||
|
(this._rQ[this._rQi++] << 8) +
|
||||||
|
this._rQ[this._rQi++];
|
||||||
|
},
|
||||||
|
|
||||||
|
rQshiftStr: function (len) {
|
||||||
|
if (typeof(len) === 'undefined') { len = this.rQlen(); }
|
||||||
|
var arr = new Uint8Array(this._rQ.buffer, this._rQi, len);
|
||||||
|
this._rQi += len;
|
||||||
|
return typedArrayToString(arr);
|
||||||
|
},
|
||||||
|
|
||||||
|
rQshiftBytes: function (len) {
|
||||||
|
if (typeof(len) === 'undefined') { len = this.rQlen(); }
|
||||||
|
this._rQi += len;
|
||||||
|
return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
|
||||||
|
},
|
||||||
|
|
||||||
|
rQshiftTo: function (target, len) {
|
||||||
|
if (len === undefined) { len = this.rQlen(); }
|
||||||
|
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ
|
||||||
|
target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
|
||||||
|
this._rQi += len;
|
||||||
|
},
|
||||||
|
|
||||||
|
rQwhole: function () {
|
||||||
|
return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
|
||||||
|
},
|
||||||
|
|
||||||
|
rQslice: function (start, end) {
|
||||||
|
if (end) {
|
||||||
|
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
|
||||||
|
} else {
|
||||||
|
return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
|
||||||
}
|
}
|
||||||
rQi -= goback;
|
},
|
||||||
}
|
|
||||||
//Util.Debug(" waiting for " + (num-rQlen) +
|
|
||||||
// " " + msg + " byte(s)");
|
|
||||||
return true; // true means need more data
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
|
||||||
// Public Send functions
|
// to be available in the receive queue. Return true if we need to
|
||||||
//
|
// wait (and possibly print a debug message), otherwise false.
|
||||||
|
rQwait: function (msg, num, goback) {
|
||||||
function flush() {
|
var rQlen = this._rQlen - this._rQi; // Skip rQlen() function call
|
||||||
if (websocket.bufferedAmount !== 0) {
|
if (rQlen < num) {
|
||||||
Util.Debug("bufferedAmount: " + websocket.bufferedAmount);
|
if (goback) {
|
||||||
}
|
if (this._rQi < goback) {
|
||||||
if (websocket.bufferedAmount < api.maxBufferedAmount) {
|
throw new Error("rQwait cannot backup " + goback + " bytes");
|
||||||
//Util.Debug("arr: " + arr);
|
}
|
||||||
//Util.Debug("sQ: " + sQ);
|
this._rQi -= goback;
|
||||||
if (sQ.length > 0) {
|
}
|
||||||
websocket.send((new Uint8Array(sQ)).buffer);
|
return true; // true means need more data
|
||||||
sQ = [];
|
}
|
||||||
}
|
return false;
|
||||||
return true;
|
},
|
||||||
} else {
|
|
||||||
Util.Info("Delaying send, bufferedAmount: " +
|
// Send Queue
|
||||||
websocket.bufferedAmount);
|
|
||||||
return false;
|
flush: function () {
|
||||||
}
|
if (this._websocket.bufferedAmount !== 0) {
|
||||||
}
|
Util.Debug("bufferedAmount: " + this._websocket.bufferedAmount);
|
||||||
|
}
|
||||||
// overridable for testing
|
|
||||||
function send(arr) {
|
if (this._websocket.bufferedAmount < this.maxBufferedAmount) {
|
||||||
//Util.Debug(">> send_array: " + arr);
|
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
|
||||||
sQ = sQ.concat(arr);
|
this._websocket.send(this._encode_message());
|
||||||
return flush();
|
this._sQlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_string(str) {
|
return true;
|
||||||
//Util.Debug(">> send_string: " + str);
|
} else {
|
||||||
api.send(str.split('').map(
|
Util.Info("Delaying send, bufferedAmount: " +
|
||||||
function (chr) { return chr.charCodeAt(0); } ) );
|
this._websocket.bufferedAmount);
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
//
|
},
|
||||||
// Other public functions
|
|
||||||
|
send: function (arr) {
|
||||||
function recv_message(e) {
|
this._sQ.set(arr, this._sQlen);
|
||||||
//Util.Debug(">> recv_message: " + e.data.length);
|
this._sQlen += arr.length;
|
||||||
|
return this.flush();
|
||||||
try {
|
},
|
||||||
var u8 = new Uint8Array(e.data);
|
|
||||||
for (var i = 0; i < u8.length; i++) {
|
send_string: function (str) {
|
||||||
rQ.push(u8[i]);
|
this.send(str.split('').map(function (chr) {
|
||||||
}
|
return chr.charCodeAt(0);
|
||||||
if (rQlen() > 0) {
|
}));
|
||||||
eventHandlers.message();
|
},
|
||||||
// Compact the receive queue
|
|
||||||
if (rQ.length > rQmax) {
|
// Event Handlers
|
||||||
//Util.Debug("Compacting receive queue");
|
off: function (evt) {
|
||||||
rQ = rQ.slice(rQi);
|
this._eventHandlers[evt] = function () {};
|
||||||
rQi = 0;
|
},
|
||||||
|
|
||||||
|
on: function (evt, handler) {
|
||||||
|
this._eventHandlers[evt] = handler;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate_buffers: function () {
|
||||||
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
|
this._sQ = new Uint8Array(this._sQbufferSize);
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function () {
|
||||||
|
this._allocate_buffers();
|
||||||
|
this._rQi = 0;
|
||||||
|
this._websocket = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function (uri, protocols) {
|
||||||
|
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
|
||||||
|
this.init();
|
||||||
|
|
||||||
|
this._websocket = new WebSocket(uri, protocols);
|
||||||
|
this._websocket.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
|
this._websocket.onmessage = this._recv_message.bind(this);
|
||||||
|
this._websocket.onopen = (function () {
|
||||||
|
Util.Debug('>> WebSock.onopen');
|
||||||
|
if (this._websocket.protocol) {
|
||||||
|
Util.Info("Server choose sub-protocol: " + this._websocket.protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._eventHandlers.open();
|
||||||
|
Util.Debug("<< WebSock.onopen");
|
||||||
|
}).bind(this);
|
||||||
|
this._websocket.onclose = (function (e) {
|
||||||
|
Util.Debug(">> WebSock.onclose");
|
||||||
|
this._eventHandlers.close(e);
|
||||||
|
Util.Debug("<< WebSock.onclose");
|
||||||
|
}).bind(this);
|
||||||
|
this._websocket.onerror = (function (e) {
|
||||||
|
Util.Debug(">> WebSock.onerror: " + e);
|
||||||
|
this._eventHandlers.error(e);
|
||||||
|
Util.Debug("<< WebSock.onerror: " + e);
|
||||||
|
}).bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function () {
|
||||||
|
if (this._websocket) {
|
||||||
|
if ((this._websocket.readyState === WebSocket.OPEN) ||
|
||||||
|
(this._websocket.readyState === WebSocket.CONNECTING)) {
|
||||||
|
Util.Info("Closing WebSocket connection");
|
||||||
|
this._websocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._websocket.onmessage = function (e) { return; };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// private methods
|
||||||
|
_encode_message: function () {
|
||||||
|
// Put in a binary arraybuffer
|
||||||
|
// according to the spec, you can send ArrayBufferViews with the send method
|
||||||
|
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
|
||||||
|
},
|
||||||
|
|
||||||
|
_expand_compact_rQ: function (min_fit) {
|
||||||
|
var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
|
||||||
|
if (resizeNeeded) {
|
||||||
|
if (!min_fit) {
|
||||||
|
// just double the size if we need to do compaction
|
||||||
|
this._rQbufferSize *= 2;
|
||||||
|
} else {
|
||||||
|
// otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
|
||||||
|
this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't want to grow unboundedly
|
||||||
|
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
||||||
|
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
||||||
|
if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) {
|
||||||
|
throw new Exception("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resizeNeeded) {
|
||||||
|
var old_rQbuffer = this._rQ.buffer;
|
||||||
|
this._rQmax = this._rQbufferSize / 8;
|
||||||
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
|
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
|
||||||
|
} else {
|
||||||
|
if (ENABLE_COPYWITHIN) {
|
||||||
|
this._rQ.copyWithin(0, this._rQi);
|
||||||
|
} else {
|
||||||
|
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._rQlen = this._rQlen - this._rQi;
|
||||||
|
this._rQi = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_decode_message: function (data) {
|
||||||
|
// push arraybuffer values onto the end
|
||||||
|
var u8 = new Uint8Array(data);
|
||||||
|
if (u8.length > this._rQbufferSize - this._rQlen) {
|
||||||
|
this._expand_compact_rQ(u8.length);
|
||||||
|
}
|
||||||
|
this._rQ.set(u8, this._rQlen);
|
||||||
|
this._rQlen += u8.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
_recv_message: function (e) {
|
||||||
|
try {
|
||||||
|
this._decode_message(e.data);
|
||||||
|
if (this.rQlen() > 0) {
|
||||||
|
this._eventHandlers.message();
|
||||||
|
// Compact the receive queue
|
||||||
|
if (this._rQlen == this._rQi) {
|
||||||
|
this._rQlen = 0;
|
||||||
|
this._rQi = 0;
|
||||||
|
} else if (this._rQlen > this._rQmax) {
|
||||||
|
this._expand_compact_rQ();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Util.Debug("Ignoring empty message");
|
||||||
|
}
|
||||||
|
} catch (exc) {
|
||||||
|
var exception_str = "";
|
||||||
|
if (exc.name) {
|
||||||
|
exception_str += "\n name: " + exc.name + "\n";
|
||||||
|
exception_str += " message: " + exc.message + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exc.description !== 'undefined') {
|
||||||
|
exception_str += " description: " + exc.description + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exc.stack !== 'undefined') {
|
||||||
|
exception_str += exc.stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception_str.length > 0) {
|
||||||
|
Util.Error("recv_message, caught exception: " + exception_str);
|
||||||
|
} else {
|
||||||
|
Util.Error("recv_message, caught exception: " + exc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exc.name !== 'undefined') {
|
||||||
|
this._eventHandlers.error(exc.name + ": " + exc.message);
|
||||||
|
} else {
|
||||||
|
this._eventHandlers.error(exc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Util.Debug("Ignoring empty message");
|
|
||||||
}
|
}
|
||||||
} catch (exc) {
|
|
||||||
if (typeof exc.stack !== 'undefined') {
|
|
||||||
Util.Warn("recv_message, caught exception: " + exc.stack);
|
|
||||||
} else if (typeof exc.description !== 'undefined') {
|
|
||||||
Util.Warn("recv_message, caught exception: " + exc.description);
|
|
||||||
} else {
|
|
||||||
Util.Warn("recv_message, caught exception:" + exc);
|
|
||||||
}
|
|
||||||
if (typeof exc.name !== 'undefined') {
|
|
||||||
eventHandlers.error(exc.name + ": " + exc.message);
|
|
||||||
} else {
|
|
||||||
eventHandlers.error(exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Util.Debug("<< recv_message");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set event handlers
|
|
||||||
function on(evt, handler) {
|
|
||||||
eventHandlers[evt] = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
rQ = [];
|
|
||||||
rQi = 0;
|
|
||||||
sQ = [];
|
|
||||||
websocket = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function open(uri, protocols) {
|
|
||||||
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
|
|
||||||
init();
|
|
||||||
|
|
||||||
if (test_mode) {
|
|
||||||
websocket = {};
|
|
||||||
} else {
|
|
||||||
websocket = new WebSocket(uri, protocols);
|
|
||||||
websocket.binaryType = 'arraybuffer';
|
|
||||||
}
|
|
||||||
|
|
||||||
websocket.onmessage = recv_message;
|
|
||||||
websocket.onopen = function() {
|
|
||||||
Util.Debug(">> WebSock.onopen");
|
|
||||||
eventHandlers.open();
|
|
||||||
Util.Debug("<< WebSock.onopen");
|
|
||||||
};
|
};
|
||||||
websocket.onclose = function(e) {
|
})();
|
||||||
Util.Debug(">> WebSock.onclose");
|
|
||||||
eventHandlers.close(e);
|
|
||||||
Util.Debug("<< WebSock.onclose");
|
|
||||||
};
|
|
||||||
websocket.onerror = function(e) {
|
|
||||||
Util.Debug(">> WebSock.onerror: " + e);
|
|
||||||
eventHandlers.error(e);
|
|
||||||
Util.Debug("<< WebSock.onerror");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
if (websocket) {
|
|
||||||
if ((websocket.readyState === WebSocket.OPEN) ||
|
|
||||||
(websocket.readyState === WebSocket.CONNECTING)) {
|
|
||||||
Util.Info("Closing WebSocket connection");
|
|
||||||
websocket.close();
|
|
||||||
}
|
|
||||||
websocket.onmessage = function (e) { return; };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override internal functions for testing
|
|
||||||
// Takes a send function, returns reference to recv function
|
|
||||||
function testMode(override_send) {
|
|
||||||
test_mode = true;
|
|
||||||
api.send = override_send;
|
|
||||||
api.close = function () {};
|
|
||||||
return recv_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructor() {
|
|
||||||
// Configuration settings
|
|
||||||
api.maxBufferedAmount = 200;
|
|
||||||
|
|
||||||
// Direct access to send and receive queues
|
|
||||||
api.get_sQ = get_sQ;
|
|
||||||
api.get_rQ = get_rQ;
|
|
||||||
api.get_rQi = get_rQi;
|
|
||||||
api.set_rQi = set_rQi;
|
|
||||||
|
|
||||||
// Routines to read from the receive queue
|
|
||||||
api.rQlen = rQlen;
|
|
||||||
api.rQpeek8 = rQpeek8;
|
|
||||||
api.rQshift8 = rQshift8;
|
|
||||||
api.rQunshift8 = rQunshift8;
|
|
||||||
api.rQshift16 = rQshift16;
|
|
||||||
api.rQshift32 = rQshift32;
|
|
||||||
api.rQshiftStr = rQshiftStr;
|
|
||||||
api.rQshiftBytes = rQshiftBytes;
|
|
||||||
api.rQslice = rQslice;
|
|
||||||
api.rQwait = rQwait;
|
|
||||||
|
|
||||||
api.flush = flush;
|
|
||||||
api.send = send;
|
|
||||||
api.send_string = send_string;
|
|
||||||
|
|
||||||
api.on = on;
|
|
||||||
api.init = init;
|
|
||||||
api.open = open;
|
|
||||||
api.close = close;
|
|
||||||
api.testMode = testMode;
|
|
||||||
|
|
||||||
return api;
|
|
||||||
}
|
|
||||||
|
|
||||||
return constructor();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -91,8 +91,8 @@
|
||||||
now = (new Date()).getTime(); // Early as possible
|
now = (new Date()).getTime(); // Early as possible
|
||||||
|
|
||||||
arr = ws.rQshiftBytes(ws.rQlen());
|
arr = ws.rQshiftBytes(ws.rQlen());
|
||||||
first = String.fromCharCode(arr.shift());
|
first = String.fromCharCode(arr[0]);
|
||||||
last = String.fromCharCode(arr.pop());
|
last = String.fromCharCode(arr[arr.length-1]);
|
||||||
|
|
||||||
if (first != "^") {
|
if (first != "^") {
|
||||||
message("Error: packet missing start char '^'");
|
message("Error: packet missing start char '^'");
|
||||||
|
@ -104,9 +104,11 @@
|
||||||
disconnect();
|
disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
arr = arr.map(function(num) {
|
text = ''
|
||||||
return String.fromCharCode(num);
|
for (var i = 1; i < arr.length-1; i++) {
|
||||||
} ).join('').split(':');
|
text += String.fromCharCode(arr[i]);
|
||||||
|
}
|
||||||
|
arr = text.split(':');
|
||||||
seq = arr[0];
|
seq = arr[0];
|
||||||
timestamp = parseInt(arr[1],10);
|
timestamp = parseInt(arr[1],10);
|
||||||
rpayload = arr[2];
|
rpayload = arr[2];
|
||||||
|
|
Loading…
Reference in New Issue