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
