Признаюсь, написал я код давно, когда был доступен только 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