VncSharp Logo

VncSharp: Architecture Overview

The following overview is provided as a starting point for anyone interested in reading and understanding the VncSharp source code. We've included it because we wished we had something like this when we were digging through the various other VNC ports!

RemoteDesktop

When we first started working we thought we wanted to create a .NET VNC Client. Once we had a basic client working, it became clear that much of what we were doing in our client could be rolled into a Custom Control, which would allow other developers to more easily re-use our work.

The RemoteDesktop control is therefore the most important class in the whole system. In it we handle all UI interaction, including keyboard and mouse handling, as well as repainting the desktop image based on local and remote events. This design allows users of the control to focus on the application and not worry about the details of implementing VNC at any level.

The RemoteDesktop control doesn't actually do any networking or other VNC protocol handling. Instead, this work is left to the VncClient class.

VncClient

The VncClient class was a late addition. Originally we did all protocol handling at the same level as the UI. However, eventually the two had grown so large that it became necessary to separate them. VncClient was created in order to wrap and hide the complexity of the protocol from the UI. As a result some users of the library might decide to use VncClient instead of the RemoteDesktop control; for example, if you wanted to build a remote capture program based on VNC.

VncClient takes care of all threading issues. In order for the UI (i.e., RemoteDesktop) to get updated images from the VNC host, the VncClient class uses a worker thread to constantly dispatch update requests, and then process them. VncClient doesn't actually do any rectangle decoding or drawing; for this it relies on the EncodedRectangleFactory class.

EncodedRectangleFactory

As the name implies EncodedRectangleFactory follows the Factory Pattern. The RFB Protocol defines various encoding strategies for reducing the size of updates being sent to the client. EncodedRectangleFactory takes care of determining which encoding type the server is sending, and then creates a derived EncodedRectangle type to actually take care of decoding and drawing the pixels.

EncodedRectangle and Derived Types

All updates sent from the VNC host are rectangular blocks of pixel or colour values. The EncodedRectangle class, and its derived types, take care of Decoding (i.e., reading the appropriate bytes from the host) and then Drawing (i.e., transferring the pixels onto the cached desktop image displayed in the RemoteDesktop control) the pixels sent from the host.

The details of how each rectangle is decoded depends on the encoding type--there are derived types for each encoding. Essentially, decoding means reading raw pixel values as integral numbers, isolating the red, green, and blue values, and then converting these to a 32-bit GDI+ pixel value, which can be easily moved into memory on the client side. For efficiency we have chosen to always represent the remote desktop using 32 bpp, regardless of what the remote system is using. As a result, some conversion is necessary to get 8 or 16 bpp pixels into 32 bpp.

Drawing the rectangle means moving the decoded pixel values into memory. The EncodedRectangle classes do not actually draw anything to the screen. Rather, they take a bitmap object that is used by the RemoteDesktop control to paint the remote image, and use pointers to alter the appropriate pixel values. This means using the unsafe keyword in order to allow pointers to access managed memory. We have chosen this approach for its efficiency, as the managed drawing calls did not provide the speed we needed.

The EncodedRectangle classes were designed to reduce the size and complexity of the RfbProtocol class.

RfbProtocol

The RfbProtocol class shows our original work in porting the Java VNC Client. RfbProtocol takes care of all protocol message passing, and helps to reduce the amount of work necessary to convert VNC RFB types into .NET types.

RfbProtocol manages a network socket and stream, and exposes methods for reading and writing the various VNC data types. In addition it handles Big- to Little-Endian conversion, and vice versa. On top of these methods are layered various protocol-level methods to simplify the complexity of setting up and tearing down a connection to a VNC host.

Conclusion

The architecture has evolved through many rewrites of the code. Much study of other VNC implementations and other open source projects--especially Mono--was necessary before we got here. If anything is clear from what has happened already, it is that this design will likely change again at some point. If you can see how it should evolve next, please let us know so we can continue to refine and improve the design.