]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/playback.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2012 Joel Martin
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';
9 import Base64
from '../core/base64.js';
12 if (setImmediate
=== undefined) {
13 var _immediateIdCounter
= 1;
14 var _immediateFuncs
= {};
16 var setImmediate = function (func
) {
17 var index
= _immediateIdCounter
++;
18 _immediateFuncs
[index
] = func
;
19 window
.postMessage("noVNC immediate trigger:" + index
, "*");
23 window
.clearImmediate = function (id
) {
27 var _onMessage = function (event
) {
28 if ((typeof event
.data
!== "string") ||
29 (event
.data
.indexOf("noVNC immediate trigger:") !== 0)) {
33 var index
= event
.data
.slice("noVNC immediate trigger:".length
);
35 var callback
= _immediateFuncs
[index
];
36 if (callback
=== undefined) {
40 delete _immediateFuncs
[index
];
44 window
.addEventListener("message", _onMessage
);
47 export default function RecordingPlayer (frames
, encoding
, disconnected
, notification
) {
48 this._frames
= frames
;
49 this._encoding
= encoding
;
51 this._disconnected
= disconnected
;
52 this._notification
= notification
;
54 if (this._encoding
=== undefined) {
55 let frame
= this._frames
[0];
56 let start
= frame
.indexOf('{', 1) + 1;
57 if (frame
.slice(start
).startsWith('UkZC')) {
58 this._encoding
= 'base64';
60 this._encoding
= 'binary';
64 this._rfb
= undefined;
65 this._frame_length
= this._frames
.length
;
67 this._frame_index
= 0;
68 this._start_time
= undefined;
69 this._realtime
= true;
70 this._trafficManagement
= true;
72 this._running
= false;
74 this.onfinish = function () {};
77 RecordingPlayer
.prototype = {
78 run: function (realtime
, trafficManagement
) {
79 // initialize a new RFB
80 this._rfb
= new RFB({'target': document
.getElementById('VNC_canvas'),
82 'onDisconnected': this._handleDisconnect
.bind(this),
83 'onNotification': this._notification
});
84 this._enablePlaybackMode();
86 // reset the frame index and timer
87 this._frame_index
= 0;
88 this._start_time
= (new Date()).getTime();
90 this._realtime
= realtime
;
91 this._trafficManagement
= (trafficManagement
=== undefined) ? !realtime
: trafficManagement
;
96 this._rfb
.connect('test', 0, 'bogus');
98 this._queueNextPacket();
101 // _enablePlaybackMode mocks out things not required for running playback
102 _enablePlaybackMode: function () {
103 this._rfb
._sock
.send = function (arr
) {};
104 this._rfb
._sock
.close = function () {};
105 this._rfb
._sock
.flush = function () {};
106 this._rfb
._checkEvents = function () {};
107 this._rfb
.connect = function (host
, port
, password
, path
) {
108 this._rfb_host
= host
;
109 this._rfb_port
= port
;
110 this._rfb_password
= (password
!== undefined) ? password
: "";
111 this._rfb_path
= (path
!== undefined) ? path
: "";
112 this._sock
.init('binary', 'ws');
113 this._rfb_connection_state
= 'connecting';
114 this._rfb_init_state
= 'ProtocolVersion';
118 _queueNextPacket: function () {
119 if (!this._running
) { return; }
121 var frame
= this._frames
[this._frame_index
];
124 while (this._frame_index
< this._frame_length
&& frame
.charAt(0) === "}") {
126 frame
= this._frames
[this._frame_index
];
129 if (frame
=== 'EOF') {
130 Log
.Debug('Finished, found EOF');
135 if (this._frame_index
>= this._frame_length
) {
136 Log
.Debug('Finished, no more frames');
141 if (this._realtime
) {
142 let foffset
= frame
.slice(1, frame
.indexOf('{', 1));
143 let toffset
= (new Date()).getTime() - this._start_time
;
144 let delay
= foffset
- toffset
;
145 if (delay
< 1) delay
= 1;
147 setTimeout(this._doPacket
.bind(this), delay
);
149 setImmediate(this._doPacket
.bind(this));
153 _doPacket: function () {
154 // Avoid having excessive queue buildup in non-realtime mode
155 if (!this._trafficManagement
&& this._rfb
._flushing
) {
157 this._rfb
.display
.set_onFlush(function () {
158 this._rfb
._display
.set_onFlush(this._rfb
._onFlush
.bind(this._rfb
));
159 this._rfb
._onFlush();
165 const frame
= this._frames
[this._frame_index
];
166 var start
= frame
.indexOf('{', 1) + 1;
167 if (this._encoding
=== 'base64') {
168 var u8
= Base64
.decode(frame
.slice(start
));
171 var u8
= new Uint8Array(frame
.length
- start
);
172 for (let i
= 0; i
< frame
.length
- start
; i
++) {
173 u8
[i
] = frame
.charCodeAt(start
+ i
);
177 this._rfb
._sock
._recv_message({'data': u8
});
180 this._queueNextPacket();
184 if (this._rfb
._display
.pending()) {
186 this._rfb
._display
.set_onFlush(function () {
187 if (player
._rfb
._flushing
) {
188 player
._rfb
._onFlush();
192 this._rfb
._display
.flush();
194 this._running
= false;
195 this.onfinish((new Date()).getTime() - this._start_time
);
199 _handleDisconnect(rfb
, reason
) {
200 this._running
= false;
201 this._disconnected(rfb
, reason
, this._frame_index
);