-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat(rfb): add encoding, FPS and bandwidth event emissions #2041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -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 } })); | ||
| } | ||
| } | ||
|
|
||
| if (!this._handleRect()) { | ||
|
|
@@ -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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
@@ -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; | ||
| } | ||
|
|
@@ -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); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
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?