| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 9. The Guacamole protocol</title><link rel="stylesheet" type="text/css" href="gug.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.78.1" /><link rel="home" href="index.html" title="Guacamole Manual" /><link rel="up" href="developers-guide.html" title="Part II. Developer's Guide" /><link rel="prev" href="developers-guide.html" title="Part II. Developer's Guide" /><link rel="next" href="libguac.html" title="Chapter 10. libguac" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"/> |
| </head><body> |
| <!-- CONTENT --> |
| |
| <div id="page"><div id="content"> |
| <div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 9. The Guacamole protocol</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="developers-guide.html">Prev</a> </td><th width="60%" align="center">Part II. Developer's Guide</th><td width="20%" align="right"> <a accesskey="n" href="libguac.html">Next</a></td></tr></table><hr /></div><div xml:lang="en" class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="guacamole-protocol"></a>Chapter 9. The Guacamole protocol</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-design">Design</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-handshake">Handshake phase</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-nesting">Nesting and interleaving</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-drawing">Drawing</a></span></dt><dd><dl><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-compositing">Compositing</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-images">Image data</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-copying-images">Copying image data between layers</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-graphical-primitives">Graphical primitives</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-layers">Buffers and layers</a></span></dt></dl></dd><dt><span class="section"><a href="guacamole-protocol.html#guacamole-audio-video">Multimedia streaming and pipes</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-events">Events</a></span></dt><dt><span class="section"><a href="guacamole-protocol.html#guacamole-protocol-disconnecting">Disconnecting</a></span></dt></dl></div> |
| |
| <a id="idm139993941791376" class="indexterm"></a> |
| <p>This chapter is an overview of the Guacamole protocol, describing its design and general |
| use. While a few instructions and their syntax will be described here, this is not an |
| exhaustive list of all available instructions. The intent is only to list the general types |
| and usage. If you are looking for the syntax or purpose of a specific instruction, consult |
| the protocol reference included with the appendices.</p> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-design"></a>Design</h2></div></div></div> |
| |
| <p>The Guacamole protocol consists of instructions. Each instruction is a comma-delimited |
| list followed by a terminating semicolon, where the first element of the list is the |
| instruction opcode, and all following elements are the arguments for that |
| instruction:</p> |
| <div class="informalexample"> |
| <pre class="programlisting"><em class="replaceable"><code>OPCODE</code></em>,<em class="replaceable"><code>ARG1</code></em>,<em class="replaceable"><code>ARG2</code></em>,<em class="replaceable"><code>ARG3</code></em>,<em class="replaceable"><code>...</code></em>;</pre> |
| </div> |
| <p>Each element of the list has a positive decimal integer length prefix separated by the |
| value of the element by a period. This length denotes the number of Unicode characters |
| in the value of the element, which is encoded in UTF-8:</p> |
| <div class="informalexample"> |
| <pre class="programlisting"><em class="replaceable"><code>LENGTH</code></em>.<em class="replaceable"><code>VALUE</code></em></pre> |
| </div> |
| <p>Any number of complete instructions make up a message which is sent from client to |
| server or from server to client. Client to server instructions are generally control |
| instructions (for connecting or disconnecting) and events (mouse and keyboard). Server |
| to client instructions are generally drawing instructions (caching, clipping, drawing |
| images), using the client as a remote display.</p> |
| <p>For example, a complete and valid instruction for setting the display size to 1024x768 |
| would be:</p> |
| <div class="informalexample"> |
| <pre class="programlisting">4.size,1.0,4.1024,3.768;</pre> |
| </div> |
| <p>Here, the instruction would be decoded into four elements: "size", the opcode of the |
| size instruction, "0", the index of the default layer, "1024", the desired width in |
| pixels, and "768", the desired height in pixels.</p> |
| <p>The structure of the Guacamole protocol is important as it allows the protocol to be |
| streamed while also being easily parsable by JavaScript. JavaScript does have native |
| support for conceptually-similar structures like XML or JSON, but neither of those |
| formats is natively supported in a way that can be streamed; JavaScript requires the |
| entirety of the XML or JSON message to be available at the time of decoding. The |
| Guacamole protocol, on the other hand, can be parsed as it is received, and the presence |
| of length prefixes within each instruction element means that the parser can quickly |
| skip around from instruction to instruction without having to iterate over every |
| character.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-handshake"></a>Handshake phase</h2></div></div></div> |
| |
| <p>The handshake phase is the phase of the protocol entered immediately upon connection. |
| It begins with a "select" instruction sent by the client which tells the server which |
| protocol will be loaded:</p> |
| <div class="informalexample"> |
| <pre class="programlisting">6.select,3.vnc;</pre> |
| </div> |
| <p>After receiving the "select" instruction, the server will load the associated client |
| support and respond with a list of accepted parameter names using an "args" |
| instruction:</p> |
| <div class="informalexample"> |
| <pre class="programlisting">4.args,8.hostname,4.port,8.password,13.swap-red-blue,9.read-only;</pre> |
| </div> |
| <p>After receiving the list of arguments, the client is required to respond with the list |
| of supported audio and video mimetypes, the optimal display size and resolution, and the |
| values for all arguments available, even if blank. If any of these requirements are left |
| out, the connection will close:</p> |
| <div class="informalexample"> |
| <pre class="programlisting">4.size,4.1024,3.768,2.96; |
| 5.audio,9.audio/ogg; |
| 5.video; |
| 7.connect,9.localhost,4.5900,0.,0.,0.;</pre> |
| </div> |
| <p>For clarity, we've put each instruction on its own line, but in the real protocol, no |
| newlines exist between instructions. In fact, if there is anything after an instruction |
| other than the start of a new instruction, the connection is closed.</p> |
| <p>Here, the client is specifying that the optimal display size is 1024x768 at 96 DPI and |
| it supports Ogg Vorbis audio, but no video. It wants to connect to localhost at port |
| 5900, and is leaving the three other parameters blank.</p> |
| <p>Once these instructions have been sent by the client, the server will attempt to |
| initialize the connection with the parameters received and, if successful, respond with |
| a "ready" instruction. This instruction contains the ID of the new client connection and |
| marks the beginning of the interactive phase. The ID is an arbitrary string, but is |
| guaranteed to be unique from all other active connections:</p> |
| <div class="informalexample"> |
| <pre class="programlisting">5.ready,37.$260d01da-779b-4ee9-afc1-c16bae885cc7;</pre> |
| </div> |
| <p>The actual interactive phase begins immediately after the "ready" instruction is sent. |
| Drawing and event instructions pass back and forth until the connection is |
| closed.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-nesting"></a>Nesting and interleaving</h2></div></div></div> |
| |
| <p>The Guacamole protocol can be nested within itself, such that long instructions or |
| independent streams of multiple instructions need not block each other; they can be |
| multiplexed into the same stream. Nesting is accomplished with the "nest" |
| instruction.</p> |
| <p>A nest instruction has only two parameters: an arbitrary integer index denoting what |
| stream the data is associated with, and the instruction data itself. The integer index |
| is important as it defines how the instruction will be reassembled. The data from nest |
| instructions with the same stream index is reassembled by the client in the order |
| received, and instructions within that data are executed immediately once |
| completed.</p> |
| <p>This is particularly important when data needs to be trickled to the client rather |
| than as a single atomic instruction.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-drawing"></a>Drawing</h2></div></div></div> |
| |
| <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="guacamole-protocol-compositing"></a>Compositing</h3></div></div></div> |
| |
| <p>The Guacamole protocol provides compositing operations through the use of "channel |
| masks". The term "channel mask" is simply a description of the mechanism used while |
| designing the protocol to conceptualize and fully enumerate all possible compositing |
| operations based on four different sources of image data: source image data where |
| the destination is opaque, source image data where the destination is transparent, |
| destination image data where the source is opaque, and destination image data where |
| the source is transparent. Assigning a binary value to each of these "channels" |
| creates a unique integer ID for every possible compositing operation, where these |
| operations parallel the operations described by Porter and Duff in their paper. As |
| the HTML5 canvas tag also uses Porter/Duff to describe their compositing operations |
| (as do other graphical APIs), the Guacamole protocol is conveniently similar to the |
| compositing support already present in web browsers, with some operations not yet |
| supported. The following operations are all implemented and known to work correctly |
| in all browsers:</p> |
| <div class="variablelist"><dl class="variablelist"><dt><span class="term">B out A (0x02)</span></dt><dd> |
| <p>Clears the destination where the source is opaque, but otherwise draws |
| nothing. This is useful for masking.</p> |
| </dd><dt><span class="term">A atop B (0x06)</span></dt><dd> |
| <p>Fills with the source where the destination is opaque only.</p> |
| </dd><dt><span class="term">A xor B (0x0A)</span></dt><dd> |
| <p>As with logical XOR. Note that this is a compositing operation, not a |
| bitwise operation. It draws the source where the destination is |
| transparent, and draws the destination where the source is |
| transparent.</p> |
| </dd><dt><span class="term">B over A (0x0B)</span></dt><dd> |
| <p>What you would typically expect when drawing, but reversed. The source |
| appears only where the destination is transparent, as if you were |
| attempting to draw the destination over the source, rather than the |
| source over the destination.</p> |
| </dd><dt><span class="term">A over B (0x0E)</span></dt><dd> |
| <p>The most common and sensible compositing operation, this draws the |
| source everywhere, but includes the destination where the source is |
| transparent.</p> |
| </dd><dt><span class="term">A + B (0x0F)</span></dt><dd> |
| <p>Simply adds the components of the source image to the destination |
| image, capping the result at pure white.</p> |
| </dd></dl></div> |
| <p>The following operations are all implemented, but may work incorrectly in WebKit |
| browsers which always include the destination image where the source is |
| transparent:</p> |
| <div class="variablelist"><dl class="variablelist"><dt><span class="term">B in A (0x01)</span></dt><dd> |
| <p>Draws the destination only where the source is opaque, clearing |
| anywhere the source or destination are transparent.</p> |
| </dd><dt><span class="term">A in B (0x04)</span></dt><dd> |
| <p>Draws the source only where the destination is opaque, clearing |
| anywhere the source or destination are transparent.</p> |
| </dd><dt><span class="term">A out B (0x08)</span></dt><dd> |
| <p>Draws the source only where the destination is transparent, clearing |
| anywhere the source or destination are opaque.</p> |
| </dd><dt><span class="term">B atop A (0x09)</span></dt><dd> |
| <p>Fills with the destination where the source is opaque only.</p> |
| </dd><dt><span class="term">A (0x0C)</span></dt><dd> |
| <p>Fills with the source, ignoring the destination entirely.</p> |
| </dd></dl></div> |
| <p>The following operations are defined, but not implemented, and do not exist as |
| operations within the HTML5 canvas:</p> |
| <div class="variablelist"><dl class="variablelist"><dt><span class="term">Clear (0x00)</span></dt><dd> |
| <p>Clears all existing image data in the destination.</p> |
| </dd><dt><span class="term">B (0x03)</span></dt><dd> |
| <p>Does nothing.</p> |
| </dd><dt><span class="term">A xnor B (0x05)</span></dt><dd> |
| <p>Adds the source to the destination where the destination or source are |
| opaque, clearing anywhere the source or destination are transparent. |
| This is similar to A + B except the aspect of transparency is also |
| additive.</p> |
| </dd><dt><span class="term">(A + B) atop B (0x07)</span></dt><dd> |
| <p>Adds the source to the destination where the destination is opaque, |
| preserving the destination otherwise.</p> |
| </dd><dt><span class="term">(A + B) atop A (0x0D)</span></dt><dd> |
| <p>Adds the destination to the source where the source is opaque, copying |
| the source otherwise.</p> |
| </dd></dl></div> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="guacamole-protocol-images"></a>Image data</h3></div></div></div> |
| |
| <p>The Guacamole protocol, like many remote desktop protocols, provides a method of |
| sending an arbitrary rectangle of image data and placing it either within a buffer |
| or in a visible rectangle of the screen. Raw image data in the Guacamole protocol is |
| sent within PNG chunks using the "png" instruction, and thus provides the same level |
| of image compression and color representation. Image updates sent in this way can be |
| RGB or RGBA (alpha transparency) and are automatically palettized if sent using |
| libguac.</p> |
| <p>Image data in the Guacamole protocol is sent base64-encoded, as the Guacamole |
| protocol is entirely text-based. This works out well, because all browsers have |
| native support for base64, and are required to at least support PNG, thus the |
| Guacamole "png" instruction is one of the more efficient ways to stream image data |
| to a browser.</p> |
| <p>Each chunk of image data can be sent to any specified rectangle within a layer or |
| buffer. Sending the data to a layer means that the image becomes immediately |
| visible, while sending the data to a buffer allows that data to be reused |
| later.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="guacamole-protocol-copying-images"></a>Copying image data between layers</h3></div></div></div> |
| |
| <p>Image data can be copied from one layer or buffer into another layer or buffer. |
| This is often used for scrolling (where most of the result of the graphical update |
| is identical to the previous state) or for caching parts of an image.</p> |
| <p>Both VNC and RDP provide a means of copying a region of screen data and placing it |
| somewhere else within the same screen. RDP provides an additional means of copying |
| data to a cache, or recalling data from that cache and placing it on the screen. |
| Guacamole takes this concept and reduces it further, as both on-screen and |
| off-screen image storage is the same. The Guacamole "copy" instruction allows you to |
| copy a rectangle of image data, and place it within another layer, whether that |
| layer is the same as the source layer, a different visible layer, or an off-screen |
| buffer.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="guacamole-graphical-primitives"></a>Graphical primitives</h3></div></div></div> |
| |
| <p>The Guacamole protocol provides basic graphics operations similar to those of |
| Cairo or the HTML5 canvas. In many cases, these primitives are useful for remote |
| drawing, and desirable in that they take up less bandwidth than sending |
| corresponding PNG images. Beware that excessive use of primitives leads to an |
| increase in client-side processing, which may reduce the performance of a connected |
| client, especially if that client is on a lower-performance machine like a mobile |
| phone or tablet.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="guacamole-protocol-layers"></a>Buffers and layers</h3></div></div></div> |
| |
| <p>All drawing operations in the Guacamole protocol affect a layer, and each layer |
| has an integer index which identifies it. When this integer is negative, the layer |
| is not visible, and can be used for storage or caching of image data. In this case, |
| the layer is referred to within the code and within documentation as a "buffer". |
| Layers are created automatically when they are first referenced in an |
| instruction.</p> |
| <p>There is one main layer which is always present called the "default layer". This |
| layer has an index of 0. Resizing this layer resizes the entire remote display. |
| Other layers default to the size of the default layer upon creation, while buffers |
| are always created with a size of 0x0, automatically resizing themselves to fit |
| their contents.</p> |
| <p>Non-buffer layers can be moved and nested within each other. In this way, layers |
| provide a simple means of hardware-accelerated compositing. If you need a window to |
| appear above others, or you have some object which will be moving or you need the |
| data beneath it automatically preserved, a layer is a good way of accomplishing |
| this. If a layer is nested within another layer, its position is relative to that of |
| its parent. When the parent is moved or reordered, the child moves with it. If the |
| child extends beyond the parents bounds, it will be clipped.</p> |
| </div> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-audio-video"></a>Multimedia streaming and pipes</h2></div></div></div> |
| |
| <p>Guacamole supports transfer of both audio and video data, as well as files and |
| arbitrary named pipes. Streams can be allocated with audio or video instructions for the |
| sake of playing media, with file instructions for file transfer, or with "pipe" |
| instructions for transfer or abtrary data between client and server.</p> |
| <p>By the nature of the Guacamole protocol, you must know the duration of the audio or |
| video data before it is sent. This is because sequential playing of multiple audio or |
| video chunks must be carefully timed by the client to avoid gaps in playback. Even a gap |
| of only one millisecond will produce an audible "click" in audio playback.</p> |
| <p>As far as audio and video are concerned, variance in chunk size gives a trade-off |
| between responsiveness and perceived quality. Larger chunks will provide smoother audio |
| and video, but have noticable lag compared to smaller chunks. Smaller chunks provide |
| less lag, but may produce noticable clicking or stutter if the timing of each chunk is |
| not perfect.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-events"></a>Events</h2></div></div></div> |
| |
| <p>When something changes on either side, client or server, such as a key being pressed, |
| the mouse moving, or clipboard data changing, an instruction describing the event is |
| sent.</p> |
| </div> |
| <div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="guacamole-protocol-disconnecting"></a>Disconnecting</h2></div></div></div> |
| |
| <p>The server and client can end the connection at any time. There is no requirement for |
| the server or the client to communicate that the connection needs to terminate. When the |
| client or server wish to end the connection, and the reason is known, they can use the |
| "disconnect" or "error" instructions.</p> |
| <p>The disconnect instruction is sent by the client when it is disconnecting. This is |
| largely out of politeness, and the server must be written knowing that the disconnect |
| instruction may not always be sent in time (guacd is written this way).</p> |
| <p>If the client does something wrong, or the server detects a problem with the client |
| plugin, the server sends an error instruction, including a description of the problem in |
| the parameters. This informs the client that the connection is being closed.</p> |
| </div> |
| </div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="developers-guide.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="developers-guide.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libguac.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part II. Developer's Guide </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 10. libguac</td></tr></table></div> |
| |
| </div></div> |
| |
| |
| <!-- Google Analytics --> |
| <script type="text/javascript"> |
| (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
| (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
| m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
| })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); |
| |
| ga('create', 'UA-75289145-1', 'auto'); |
| ga('send', 'pageview'); |
| |
| </script> |
| <!-- End Google Analytics --> |
| </body></html> |