On Fri, Apr 28, 2017 at 4:31 AM, Nick Couchman <
[email protected]> wrote:

>
> > I'm reading the code of Guacamole for the purpose of learning , and I
> want to know why  chose Base64 to encode image data. As far as I know, it
> will enlarge the total size of data transmission over network. Why not just
> send binary data? I have read the official document, and it said:
>
> Mike or James can probably answer this better, but I think there are two
> reasons:- We're not just transmitting the binary data (the image, for
> example), we also need to transmit metadata about the binary data, and we
> want the metadata to arrive at the same time as the binary data.  So, we
> encode it all in a stream and send it all at the same time, then decode it
> on the other end, and we get the binary data (the actual object) along with
> the information we need about the object.


This is correct, and is partly why images are transmitted in-band, but
doesn't itself exclude the possibility of using binary.


> - We're transmitting the data over HTTP, which, in a lot of situations, is
> picky about the characters it deals with.


Not quite - we're transmitting over either HTTP or WebSocket. HTTP is not
picky about the characters it deals with, but the JavaScript side of things
is. While WebSocket does have support for streaming binary data,
XMLHttpRequest (the JavaScript object we use to read the streaming data)
does not. Switching to binary in the case of HTTP would mean major
sacrifices in terms of responsiveness.

But since WebSocket does support binary, why not use binary in at least
that case?

In the early days of Guacamole, the reason for using base64 despite the 4/3
expansion ratio was that browsers had poor support for binary data, or
lacked that support entirely. Receiving text frames via WebSocket (or
streaming text data via HTTP through XMLHttpRequest) was reliable, but
receiving binary frames via WebSocket was not. Even with the browsers that
supported binary frames via WebSocket, parsing that data in binary form was
much slower than just using the browser's native base64 support.

Now, though browser support for binary has improved, base64 is still much
faster. There's more to remote desktop than raw bandwidth use, and in
practice that 4/3 expansion is negligible compared to the improvements in
responsiveness gained through avoiding binary decoding.

The alternative to using base64 and decoding through data URIs would be
ArrayBuffers and decoding using Blobs and Blob URLs. ArrayBuffers are quite
fast, but decoding Blobs via Blob URLs is not, particularly for smaller
images. In the most common case (where changes to the screen involve
smaller, incremental changes), user experience suffers dramatically when
binary is used compared to base64.

I actually did a proof-of-concept comparison between base64 and binary the
other day, to determine whether the above findings were still the case, and
indeed they are. Performing the same series of actions over an RDP
connection through Guacamole, average bandwidth usage for both connections
was 289 Kbps. The only noticeable difference was that stock 0.9.12 was
quite fast, with response following action closely enough that it was
difficult to distinguish from local, while 0.9.12 modified for binary image
transmission was extremely sluggish, particularly for sequences of actions
like scrolling or interacting with a menu.

Base64 is definitely still the way to go.

- Mike

Reply via email to