Pull to refresh

Реализация VNC клиента

Reading time3 min
Views11K
Original author: Silverlight Playground


Признаюсь, написал я код давно, когда был доступен только Silverlight 3.0 и отложил на полочку до прихода лучших времен, потому что как пример он был отличным, а вот пользы, почти, никакой. По причине использования сокетов, которые усложняли всю работу, так как мы должны были иметь в наличии сервер авторизации, в общем с портами была еще та катавасия.

Наконец, после первого проблеска Silverlight 4.0, я решил достань запылившийся код и толкнуть это дело в народ и все благодаря новому функционалу – запуск приложений вне браузера (OOB). Теперь я мог расслабиться с сокетами, приложение устанавливается как полностью доверительное и я волен работать с любым сервисом на основе сокетов и больше не нужно иметь в наличии policy-сервер.

Итак представляю вашему вниманию SilverVNC, базовую реализацию Remote Framebuffer протокола (RFB), со спецификациями вы можете ознакомиться на сайте RealVNC. Реализацию протокола производил с помощью последней верси UltraVNC.

Как я уже сказал, реализация базовая. В отличии от коммерческой версии, я поддерживаю только RAW-кодирование и не использую компрессию какого-либо типа… Потому что обработка тяжелых сокет-связей с помощью асинхронной модели в silverlight — своего рода хождение по лезвию, вроде просто, а в реальности все гораздо серьезней и сложнее. Так что я решил предоставить пользователю простой пример, как оно работает.

Принцип работы


Ядром примера, является класс RfbClient, который инкапсулирует всю нужную логику для связи с сервером, декодирования данных и отправки событий пользовательскому интерфейсу. Класс состоит из метродов, которые принимают и отправляют данные в сокет. Не буду углубляться в недра класса, потому что описание спецификации RFB-протокола не входит в данную статью. Вам нужно только знать, что благодаря OOB приложение может открывать сокет на любом порту без никаких разрешений.

Главная страница приложения  использует RfbClient для подключения к VNC сервера и тянет с него данные и декодирует. Каждый раз, когда RfbClient что-то получает, то вызывает два типа события:

ResizeFrameBuffer – сервер уведомил о изменении размеров экрана. Это обычно происходит в начале подключения для того, чтобы клиент изменил размер области отрисовки.

FramBufferUpdate – сервер определил изменения на экране, вырезал измененный участок и передал на сервер. Обработчик события рассчитал позицию квадрата на отрисовываемой области и вывел его на экран.

Вот пример обработки этих событий:

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();
}

Что дальше?


Я думаю, вскоре я добавлю еще некоторый функционал и улучшения. Прежде всего я размышляю над написанием алгоритма записи в буфер, он должен быть более эффективным, чем код показанный выше. Мой идея – реализовать MediaStreamSource, для предоставления видео потока, который можно подключить к MediaElement. Это должно быть лучше не только с точки зрения производительности, но и простоты использования для разработчиков, которым нужно добавить просмоторщик удаленного рабочего стола в свои приложения.

Другим улучшением будет реализация другого алгоритма компрессии. Возможно я реализую RRE, CoreRRE и Hex. Наконец я хотел мы развить просмоторщик до полнофункционального приложения для просмотра удаленного рабочего стола. По идее это сделать не сложно.

А пока, прошу попробовать текущее приложения и хочу услышать отзывы.

Исходный код: http://www.silverlightplayground.org/assets/sources/SilverlightPlayground.RFB.zip
Видео: http://www.silverlightplayground.org/assets/video/SilverVNC.wmv
RFB спецификации: The RFB Protocol

Источник — Silverlight Playground
Tags:
Hubs:
Total votes 36: ↑25 and ↓11+14
Comments4

Articles