📜 ⬆️ ⬇️

VNC client implementation



I admit, I wrote the code a long time ago when only Silverlight 3.0 was available and put it on a shelf until the arrival of better times, because as an example it was excellent, but there was almost no benefit. Due to the use of sockets, which complicated all the work, since we had to have an authorization server available, in general, the ports were still confused.

Finally, after the first glimpse of Silverlight 4.0, I decided to get the dusty code and push this thing into the people and all thanks to a new functionality - launching applications outside the browser (OOB). Now I could relax with sockets, the application is installed as fully trusted and I am free to work with any socket-based service and I no longer need to have a policy server available.
')
So I present to your attention the SilverVNC, the basic implementation of the Remote Framebuffer protocol (RFB), with the specifications you can find on the RealVNC website . The protocol was implemented using the latest version of UltraVNC.

As I said, the implementation is basic. Unlike the commercial version, I support only RAW coding and do not use any type of compression ... Because processing heavy socket connections using the asynchronous model in silverlight is a kind of blade walking, it seems to be simple, but in reality everything is much more serious and harder. So I decided to provide the user with a simple example of how it works.

Principle of operation


The core of the example is the RfbClient class , which encapsulates all the necessary logic to communicate with the server, decode data, and send events to the user interface. The class consists of metrods that receive and send data to the socket. I will not delve into the depths of the class, because the description of the RFB protocol specification is not included in this article. You just need to know that thanks to OOB, an application can open a socket on any port without any permissions.

The application home page uses RfbClient to connect to the server's VNC and pulls data from it and decodes it. Each time an RfbClient receives something, it raises two types of events:

ResizeFrameBuffer - the server notified of screen resizing. This usually occurs at the beginning of the connection in order for the client to change the size of the drawing area.

FramBufferUpdate - the server detected the changes on the screen, cut out the modified section and transmitted to the server. The event handler calculated the position of the square on the drawing area and displayed it on the screen.

Here is an example of handling these events:

void Client_ResizeFrameBuffer( object sender, EventArgs e)
{
this .MakeWindowProportional( this .Client.Server.Width, this .Client.Server.Height);
this .BitMap = new WriteableBitmap( this .Client.Server.Width, this .Client.Server.Height);
this .vnc.Source = this .BitMap;
}

private void MakeWindowProportional( double width, double height)
{
double proportion = width / height;
Application.Current.MainWindow.Height = Application.Current.MainWindow.Width / proportion;
Application.Current.MainWindow.Activate();
}

private void Client_FrameBufferUpdate( object sender, FrameBufferUpdateEventArgs e)
{
Rect rect = e.Rectangle;

int x = 0;
int y = 0;

foreach ( uint color in e.Colors)
{

this .BitMap.Pixels[
(y + ( int )rect.Y) *
this .Client.Server.Width +
(x + ( int )rect.X)] = ( int )color;

if (++x == rect.Width)
{
x = 0;
y++;
}
}

this .BitMap.Invalidate();
}

What's next?


I think soon I will add some more features and improvements. First of all, I think about writing the buffer writing algorithm, it should be more efficient than the code shown above. My idea is to implement MediaStreamSource to provide a video stream that can be connected to a MediaElement. This should be better not only in terms of performance, but also ease of use for developers who need to add a remote desktop viewer to their applications.

Another improvement will be the implementation of a different compression algorithm. Perhaps I implement RRE, CoreRRE and Hex. Finally, I wanted to develop the viewer to a full-featured remote desktop viewing application. In theory, this is not difficult to do.

In the meantime, please try the current application and want to hear feedback.

Source code: http://www.silverlightplayground.org/assets/sources/SilverlightPlayground.RFB.zip
Video: http://www.silverlightplayground.org/assets/video/SilverVNC.wmv
RFB Specifications: The RFB Protocol

Source - Silverlight Playground

Source: https://habr.com/ru/post/88594/


All Articles