Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions core/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ export default class RFB extends EventTargetMixin {
encoding: null,
};

// Encoding and FPS tracking
this._lastEncoding = null;
this._frameCount = 0;
this._lastFpsTime = performance.now();
this._lastBandwidthTime = performance.now();

// Mouse state
this._mousePos = {};
this._mouseButtonMask = 0;
Expand Down Expand Up @@ -2663,6 +2669,13 @@ export default class RFB extends EventTargetMixin {
this._FBU.encoding = this._sock.rQshift32();
/* Encodings are signed */
this._FBU.encoding >>= 0;

// Emit encoding change event for real encodings (not pseudo-encodings)
if (this._lastEncoding !== this._FBU.encoding && this._FBU.encoding >= 0) {
this._lastEncoding = this._FBU.encoding;
this.dispatchEvent(new CustomEvent("encodingchange",
{ detail: { encoding: this._FBU.encoding } }));
}
Comment on lines +2673 to +2678
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encodings can change multiple times per update, so this is not a productive approach.

What information is it you want to present here?

}

if (!this._handleRect()) {
Expand All @@ -2675,6 +2688,25 @@ export default class RFB extends EventTargetMixin {

this._display.flip();

// FPS counter
this._frameCount++;
const now = performance.now();
if (now - this._lastFpsTime >= 1000) {
this.dispatchEvent(new CustomEvent("fps",
{ detail: { fps: this._frameCount } }));
this._frameCount = 0;
this._lastFpsTime = now;
}
Comment on lines +2694 to +2699
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statistics is messy and people will likely want to measure things in different ways with different degrees of accuracy.

Can't we just expose the raw data and let the caller deal with how to aggregate that?

I.e. expose a frame counter and the number of transferred bytes.


// Bandwidth counter (every 2 seconds for smoother readings)
if (now - this._lastBandwidthTime >= 2000) {
const stats = this._sock.getBandwidthStats();
this.dispatchEvent(new CustomEvent("bandwidth",
{ detail: stats }));
this._sock.resetBandwidthStats();
this._lastBandwidthTime = now;
}

return true; // We finished this FBU
}

Expand Down
30 changes: 30 additions & 0 deletions core/websock.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ export default class Websock {
close: () => {},
error: () => {}
};

// Bandwidth tracking
this._bytesReceived = 0;
this._bytesSent = 0;
this._bandwidthStartTime = performance.now();
}

// Bandwidth statistics
getBandwidthStats() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also update the documentation with all API changes.

const now = performance.now();
const elapsed = (now - this._bandwidthStartTime) / 1000; // seconds
if (elapsed < 0.1) return { down: 0, up: 0, totalDown: 0, totalUp: 0 };

const downKbps = (this._bytesReceived * 8 / 1000) / elapsed;
const upKbps = (this._bytesSent * 8 / 1000) / elapsed;

return {
down: downKbps,
up: upKbps,
totalDown: this._bytesReceived,
totalUp: this._bytesSent
};
}

resetBandwidthStats() {
this._bytesReceived = 0;
this._bytesSent = 0;
this._bandwidthStartTime = performance.now();
}

// Getters and setters
Expand Down Expand Up @@ -220,6 +248,7 @@ export default class Websock {

flush() {
if (this._sQlen > 0 && this.readyState === 'open') {
this._bytesSent += this._sQlen;
this._websocket.send(new Uint8Array(this._sQ.buffer, 0, this._sQlen));
this._sQlen = 0;
}
Expand Down Expand Up @@ -354,6 +383,7 @@ export default class Websock {
this._rQi = 0;
}
const u8 = new Uint8Array(e.data);
this._bytesReceived += u8.length;
if (u8.length > this._rQbufferSize - this._rQlen) {
this._expandCompactRQ(u8.length);
}
Expand Down