Silverlight: Реализация VNC клиента
Признаюсь, написал я код давно, когда был доступен только Silverlight 3.0 и отложил на полочку до прихода лучших времен, потому что как пример он был отличным, а вот пользы, почти, никакой. По причине использования сокетов, которые усложняли всю работу, так как мы должны были иметь в наличии сервер авторизации, в общем с портами была еще та катавасия.
Наконец, после первого проблеска Silverlight 4.0, я решил достань запылившийся код и толкнуть это дело в народ и все благодаря новому функционалу – запуск приложений вне браузера (OOB). Теперь я мог расслабиться с сокетами, приложение устанавливается как полностью доверительное и я волен работать с любым сервисом на основе сокетов и больше не нужно иметь в наличии policy-сервер.
Итак представляю вашему вниманию SilverVNC, базовую реализацию Remote Framebuffer протокола (RFB), со спецификациями вы можете ознакомиться на сайте RealVNC. Реализацию протокола производил с помощью последней верси UltraVNC.
Как я уже сказал, реализация базовая. В отличии от коммерческой версии, я поддерживаю только RAW-кодирование и не использую компрессию какого-либо типа.. Потому что обработка тяжелых сокет-связей с помощью асинхронной модели в silverlight - своего рода хождение по лезвию, вроде просто, а в реальности все гораздо серьезней и сложнее. Так что я решил предоставить пользователю простой пример, как оно работает.
Принцип работы
Ядром примера, является класс RfbClient, который инкапсулирует всю нужную логику для связи с сервером, декодирования данных и отправки событий пользовательскому интерфейсу. Класс состоит из метродов, которые принимают и отправляют данные в сокет. Не буду углубляться в недра класса, потому что описание спецификации RFB-протокола не входит в данную статью. Вам нужно только знать, что благодаря OOB приложение может открывать сокет на любом порту без никаких разрешений.
Главная страница приложения использует RfbClient для подключения к VNC сервера и тянет с него данные и декодирует. Каждый раз, когда RfbClient что-то получает, то вызывает два типа события:
ResizeFrameBuffer – сервер уведомил о изменении размеров экрана. Это обычно происходит в начале подключения для того, чтобы клиент изменил размер области отрисовки.
FramBufferUpdate – сервер определил изменения на экране, вырезал измененный участок и передал на сервер. Обработчик события рассчитал позицию квадрата на отрисовываемой области и вывел его на экран.
Вот пример обработки этих событий:
1: void Client_ResizeFrameBuffer(object sender, EventArgs e)
2: {
3: this.MakeWindowProportional(this.Client.Server.Width, this.Client.Server.Height);
4: this.BitMap = new WriteableBitmap(this.Client.Server.Width, this.Client.Server.Height);
5: this.vnc.Source = this.BitMap;
6: }
7:
8: private void MakeWindowProportional(double width, double height)
9: {
10: double proportion = width / height;
11: Application.Current.MainWindow.Height = Application.Current.MainWindow.Width / proportion;
12: Application.Current.MainWindow.Activate();
13: }
14:
15: private void Client_FrameBufferUpdate(object sender, FrameBufferUpdateEventArgs e)
16: {
17: Rect rect = e.Rectangle;
18:
19: int x = 0;
20: int y = 0;
21:
22: foreach (uint color in e.Colors)
23: {
24: this.BitMap.Pixels[
25: (y + (int)rect.Y) *
26: this.Client.Server.Width +
27: (x + (int)rect.X)] = (int)color;
28:
29: if (++x == rect.Width)
30: {
31: x = 0;
32: y++;
33: }
34: }
35:
36: this.BitMap.Invalidate();
37: }
Что дальше?
Я думаю, вскоре я добавлю еще некоторый функционал и улучшения. Прежде всего я размышляю над написанием алгоритма записи в буфер, он должен быть более эффективным, чем код показанный выше. Мой идея – реализовать 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