]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/playback.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2018 The noVNC Authors
4 * Licensed under MPL 2.0 (see LICENSE.txt)
7 import RFB
from '../core/rfb.js';
8 import * as Log
from '../core/util/logging.js';
11 if (window
.setImmediate
=== undefined) {
12 let _immediateIdCounter
= 1;
13 const _immediateFuncs
= {};
15 window
.setImmediate
= (func
) => {
16 const index
= _immediateIdCounter
++;
17 _immediateFuncs
[index
] = func
;
18 window
.postMessage("noVNC immediate trigger:" + index
, "*");
22 window
.clearImmediate
= (id
) => {
26 window
.addEventListener("message", (event
) => {
27 if ((typeof event
.data
!== "string") ||
28 (event
.data
.indexOf("noVNC immediate trigger:") !== 0)) {
32 const index
= event
.data
.slice("noVNC immediate trigger:".length
);
34 const callback
= _immediateFuncs
[index
];
35 if (callback
=== undefined) {
39 delete _immediateFuncs
[index
];
45 export default class RecordingPlayer
{
46 constructor(frames
, disconnected
) {
47 this._frames
= frames
;
49 this._disconnected
= disconnected
;
51 this._rfb
= undefined;
52 this._frame_length
= this._frames
.length
;
54 this._frame_index
= 0;
55 this._start_time
= undefined;
56 this._realtime
= true;
57 this._trafficManagement
= true;
59 this._running
= false;
61 this.onfinish
= () => {};
64 run(realtime
, trafficManagement
) {
65 // initialize a new RFB
66 this._rfb
= new RFB(document
.getElementById('VNC_screen'), 'wss://test');
67 this._rfb
.viewOnly
= true;
68 this._rfb
.addEventListener("disconnect",
69 this._handleDisconnect
.bind(this));
70 this._rfb
.addEventListener("credentialsrequired",
71 this._handleCredentials
.bind(this));
72 this._enablePlaybackMode();
74 // reset the frame index and timer
75 this._frame_index
= 0;
76 this._start_time
= (new Date()).getTime();
78 this._realtime
= realtime
;
79 this._trafficManagement
= (trafficManagement
=== undefined) ? !realtime
: trafficManagement
;
84 // _enablePlaybackMode mocks out things not required for running playback
85 _enablePlaybackMode() {
87 this._rfb
._sock
.send
= () => {};
88 this._rfb
._sock
.close
= () => {};
89 this._rfb
._sock
.flush
= () => {};
90 this._rfb
._sock
.open = function () {
92 this._eventHandlers
.open();
93 self
._queueNextPacket();
98 if (!this._running
) { return; }
100 let frame
= this._frames
[this._frame_index
];
103 while (this._frame_index
< this._frame_length
&& frame
.fromClient
) {
105 frame
= this._frames
[this._frame_index
];
108 if (this._frame_index
>= this._frame_length
) {
109 Log
.Debug('Finished, no more frames');
114 if (this._realtime
) {
115 const toffset
= (new Date()).getTime() - this._start_time
;
116 let delay
= frame
.timestamp
- toffset
;
117 if (delay
< 1) delay
= 1;
119 setTimeout(this._doPacket
.bind(this), delay
);
121 setImmediate(this._doPacket
.bind(this));
126 // Avoid having excessive queue buildup in non-realtime mode
127 if (this._trafficManagement
&& this._rfb
._flushing
) {
128 const orig
= this._rfb
._display
.onflush
;
129 this._rfb
._display
.onflush
= () => {
130 this._rfb
._display
.onflush
= orig
;
131 this._rfb
._onFlush();
137 const frame
= this._frames
[this._frame_index
];
139 this._rfb
._sock
._recv_message({'data': frame
.data
});
142 this._queueNextPacket();
146 if (this._rfb
._display
.pending()) {
147 this._rfb
._display
.onflush
= () => {
148 if (this._rfb
._flushing
) {
149 this._rfb
._onFlush();
153 this._rfb
._display
.flush();
155 this._running
= false;
156 this._rfb
._sock
._eventHandlers
.close({code
: 1000, reason
: ""});
158 this.onfinish((new Date()).getTime() - this._start_time
);
162 _handleDisconnect(evt
) {
163 this._running
= false;
164 this._disconnected(evt
.detail
.clean
, this._frame_index
);
167 _handleCredentials(evt
) {
168 this._rfb
.sendCredentials({"username": "Foo",