How DeskRoll Uses New Web Technologies

Today we will take a look at the inner workings of a remote desktop system. It is called DeskRoll, and it uses a lot of modern technologies such as HTML5 and WebRTC that bring the possibility of a remote desktop system to the browser. DeskRoll is primarily intended for individuals and small companies who need a simple remote access tool. We won’t be describing the system entirely. Instead we will concentrate on the new technologies which allow you to watch a remote desktop and control it. In addition, we will try to analyze some visible code of the system which is written in Javascript.

What is DeskRoll

In the terminology of DeskRoll the local side is called the Technician’s Viewport. It is written in pure HTML5 and JS and works in any modern browsers including tablet ones. The remote side is called the Client. Right now there are two components of the remote access software - DeskRoll Remote Desktop and DeskRoll Unattended Access.

The first one allows you to do remote support. It means that someone should be present at the remote computer and confirm your remote control request. Only after the confirmation does the control session start. This component runs without installation and does not require administrative rights. Your client may choose to keep the software and be able to start it as a link from their desktop anytime.

The second component allows you to do unattended access. Using a special code, you should link a new computer to your account. Then you will be able to control your PC at any time. The DeskRoll license does not limit the number of computers you can use this on; the only limitation is one account for one technician.

Architecture

Let’s talk about the architecture of the system. Monitoring of network activity shows that it uses polling (a request every 200 ms) to send current state of Technician’s Viewport (mouse/keyboard events, etc) and get the client data including the remote desktop image from the central server.

The system uses PNG pictures and the HTML5 canvas tag to draw the remote desktop on the local side. Using Firebug we see that depending on the selected speed mode, DeskRoll uses PNGA or palette-based PNG. In the case of the Max Speed option two pixels are placed into one byte (i.e. 4-bit palette). Depending on the picture size, it is packed on the client side (or on the central server) to a binary format or to Base64. Base64 pictures are received via the polling. To get binary images, the viewport makes separate requests using the Image Javascript object.

In terms of state-of-the-art technology, the main feature of the system is P2P in Google Chrome, without any plugins. Here P2P uses the WebRTC data channel. If P2P connection is possible in the given network environment, the remote desktop and control events are transmitted through the WebRTC data channel. The server channel is used only for some service information and for rare events like remote reboot.

Under the Hood

If we take a peek at the JavaScript code, we’ll notice that WebRTC does not have a stream data channel yet. It does not guarantee the correct order of packets. Moreover, it does not guarantee delivery at all.

In the DeskRoll code there is a special module which is called DeskRoll.WebRtcHelper. It receives packets in special portions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
onData: function(data) {
var p;

if (parseInt(data.b) == this.blockId) {
if (data.c) {
this.count = parseInt(data.c);

if (this.packetStartId == this.count) {
this.processBlockReceived();
} else {
this.requestLostPackets();
}
} else {
p = parseInt(data.p);
this.checkPacketsLength(p);
this.packets[p] = data.d;

if (p != 0 && this.count == 0 && this.packets[p - 1] == null) {
this.sendBlockMissed(p - 1);
}

this.size = p + 1;
this.processPackets();
}
}
},

DeskRoll creates a list of parts of images using a Javasript array. If some parts are not received, DeskRoll requests them again.

1
2
3
4
5
6
7
8
sendBlockMissed: function(i) {
var data = { events: [{ et: 10, type: 3, b: this.blockId, p: i }] };

try {
this.dataChannel.send(JSON.stringify(data));
} catch(e) {
}
},

Then it restores the correct order of image portions and combines them into a final image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
processPacketsLoop: function() {
var i, d, limit = (this.count > 0) ? this.count : this.size;

for (i = this.packetStartId; i < limit; i++) {
if (this.packets[i] == null) break;

if (parseInt(this.packets[i].f)) {
d = this.packets[i].d;
} else {
d += this.packets[i].d;
}

if (parseInt(this.packets[i].l)) {
if (parseInt(this.packets[i].sw) > 0) {
this.setScreenInfo(this.packets[i]);
}

this.drawImage(this.packets[i], d, i);
break;
}
}
},

drawImage: function(data, d, i) {
var image = new Image();
this.busy = true;

image.onload = $.proxy(function() {
this.canvasModule.draw(image, data.x, data.y, this.canvasImageId, data.dl);
this.canvasImageId++;
this.packetStartId = i + 1;
this.busy = false;

if (this.count != 0 &amp;&amp; this.count == this.packetStartId) {
this.processBlockReceived();
} else {
this.processPackets();
}
}, this);

image.src = 'data:image/png;base64,' + d;
},

Despite its relative newness and being implemented in a browser, the performance holds up very well.

Conclusion

If you’d like to see the full source code to try to understand it better for yourself, you can “View Source” here. It really is amazing what the new browser technologies have allowed us to do without plug-ins. The future for HTML, CSS, and JavaScript look very bright.

Author: Guest

Author: Guest Sometimes someone asks if they can write for the blog. They may want to just work on their own writing chops, get their foot in the blogging door, or maybe they want to show off something they've done. In any case, they are a guest author and this post happens to be written by one; please enjoy the hard work they've done to put this article together.