Commit 9ff86fb7 authored by Solly Ross's avatar Solly Ross

Use Typed Arrays for the send queue

This commit converts the send queue to use typed arrays, and converts
message creation functions in 'rfb.js' to create messages directly into
the socket's send queue.  This commit also removes the separate mouse array,
which is no longer needed.
parent d1800d09
This diff is collapsed.
......@@ -45,10 +45,14 @@ function Websock() {
this._rQlen = 0; // Next write position in the receive queue
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
this._rQmax = this._rQbufferSize / 8;
this._sQ = []; // Send queue
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ = null; // Receive queue
this._sQbufferSize = 1024 * 10; // 10 KiB
// called in init: this._sQ = new Uint8Array(this._sQbufferSize);
this._sQlen = 0;
this._sQ = null; // Send queue
this._mode = 'binary'; // Current WebSocket mode: 'binary', 'base64'
this.maxBufferedAmount = 200;
......@@ -183,9 +187,9 @@ function Websock() {
}
if (this._websocket.bufferedAmount < this.maxBufferedAmount) {
if (this._sQ.length > 0) {
if (this._sQlen > 0) {
this._websocket.send(this._encode_message());
this._sQ = [];
this._sQlen = 0;
}
return true;
......@@ -197,7 +201,8 @@ function Websock() {
},
send: function (arr) {
this._sQ = this._sQ.concat(arr);
this._sQ.set(arr, this._sQlen);
this._sQlen += arr.length;
return this.flush();
},
......@@ -218,12 +223,12 @@ function Websock() {
_allocate_buffers: function () {
this._rQ = new Uint8Array(this._rQbufferSize);
this._sQ = new Uint8Array(this._sQbufferSize);
},
init: function (protocols, ws_schema) {
this._allocate_buffers();
this._rQi = 0;
this._sQ = [];
this._websocket = null;
// Check for full typed array support
......@@ -327,7 +332,8 @@ function Websock() {
// private methods
_encode_message: function () {
// Put in a binary arraybuffer
return (new Uint8Array(this._sQ)).buffer;
// according to the spec, you can send ArrayBufferViews with the send method
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
},
_decode_message: function (data) {
......
......@@ -24,6 +24,12 @@ chai.use(function (_chai, utils) {
_chai.Assertion.addMethod('sent', function (target_data) {
var obj = this._obj;
obj.inspect = function () {
var res = { _websocket: obj._websocket, rQi: obj._rQi, _rQ: new Uint8Array(obj._rQ.buffer, 0, obj._rQlen),
_sQ: new Uint8Array(obj._sQ.buffer, 0, obj._sQlen) };
res.prototype = obj;
return res;
};
var data = obj._websocket._get_sent_data();
var same = true;
for (var i = 0; i < obj.length; i++) {
......@@ -38,8 +44,8 @@ chai.use(function (_chai, utils) {
this.assert(same,
"expected #{this} to have sent the data #{exp}, but it actually sent #{act}",
"expected #{this} not to have sent the data #{act}",
target_data,
data);
Array.prototype.slice.call(target_data),
Array.prototype.slice.call(data));
});
_chai.Assertion.addProperty('array', function () {
......
......@@ -51,14 +51,9 @@ var FakeWebSocket;
},
_get_sent_data: function () {
var arr = [];
for (var i = 0; i < this.bufferedAmount; i++) {
arr[i] = this._send_queue[i];
}
var res = new Uint8Array(this._send_queue.buffer, 0, this.bufferedAmount);
this.bufferedAmount = 0;
return arr;
return res;
},
_open: function (data) {
......
This diff is collapsed.
......@@ -173,7 +173,8 @@ describe('Websock', function() {
it('should actually send on the websocket if the websocket does not have too much buffered', function () {
sock.maxBufferedAmount = 10;
sock._websocket.bufferedAmount = 8;
sock._sQ = [1, 2, 3];
sock._sQ = new Uint8Array([1, 2, 3]);
sock._sQlen = 3;
var encoded = sock._encode_message();
sock.flush();
......@@ -189,7 +190,7 @@ describe('Websock', function() {
});
it('should not call send if we do not have anything queued up', function () {
sock._sQ = [];
sock._sQlen = 0;
sock.maxBufferedAmount = 10;
sock._websocket.bufferedAmount = 8;
......@@ -215,7 +216,7 @@ describe('Websock', function() {
it('should add to the send queue', function () {
sock.send([1, 2, 3]);
var sq = sock.get_sQ();
expect(sock.get_sQ().slice(sq.length - 3)).to.deep.equal([1, 2, 3]);
expect(new Uint8Array(sq.buffer, sock._sQlen - 3, 3)).to.array.equal(new Uint8Array([1, 2, 3]));
});
it('should call flush', function () {
......@@ -425,15 +426,16 @@ describe('Websock', function() {
sock._websocket._open();
});
it('should convert the send queue into an ArrayBuffer', function () {
sock._sQ = [1, 2, 3];
var res = sock._encode_message(); // An ArrayBuffer
expect(new Uint8Array(res)).to.deep.equal(new Uint8Array(res));
it('should only send the send queue up to the send queue length', function () {
sock._sQ = new Uint8Array([1, 2, 3, 4, 5]);
sock._sQlen = 3;
var res = sock._encode_message();
expect(res).to.array.equal(new Uint8Array([1, 2, 3]));
});
it('should properly pass the encoded data off to the actual WebSocket', function () {
sock.send([1, 2, 3]);
expect(sock._websocket._get_sent_data()).to.deep.equal([1, 2, 3]);
expect(sock._websocket._get_sent_data()).to.array.equal(new Uint8Array([1, 2, 3]));
});
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment