Programando un cliente VNC con WebSockets y Perl

Hace unas semanas, vti, un programador que se autodenomina "hacker de Perl", publicó un artículo sobre cómo desarrollar un cliente VNC usando WebSockets que por su simplicidad y lo didáctico de su solución merecen una reseña. Si estamos familiarizados con el modelo VNC sabremos que usa el protocolo RFB y que hay multitud de clientes de escritorio y de servidores que lo usan, de hecho en algunos sistemas operativos o distribuciones viene ya de serie como en Ubuntu, Fedora o Mac OS.

Usando Perl y CPAN el único módulo que funciona con VNC es Net::VNC, pero sólo captura un screenshot y no es útil para cosas más alla de eso. Es por eso que vti tuvo que desarrollar Protocol::RFB, el cual aún no está finalizado pero puede parsear los mensajes RFB incluyendo las interacciones de teclado y ratón. Asegura que publicará dicho módulo en CPAN para su disfrute general.

Otro asunto es el servidor de WebSockets. En una versión anterior de showmethedesktop, el nombre que le ha dado al software, usó Mojolicious para WebSockets y parseo de JSON, pero WebSockets estaba sin terminar y Mojolicious no soporta todos los protocolos necesarios. Además vti necesitaba un mecanismo para conectar los WebSockets a sockets normales, así que, en vez de usar Mojo::IOLoop, que requería trastear demasiado a bajo nivel, pasó a crear su propia herramienta: reanimator

Para explicar su funcionamiento el autor usa este trozo de código:

        my $server = ReAnimator->new;

        $server->on_connect(
            sub {
                my ($self, $client) = @_;

                my $vnc = Protocol::RFB::Client
                        ->new(password => 'vnc password');

                my $slave = $self->connect(
                    address => 'localhost',
                    port    => '5901',
                    on_read => sub {
                        my $slave = shift;
                        my $chunk = shift;

                        $vnc->parse($chunk);
                    }
                );

                $vnc->on_write(
                    sub {
                        my ($vnc, $chunk) = @_;

                        $slave->write($chunk);
                    }
                );

                $vnc->on_framebuffer_update(
                    sub {
                        my ($vnc, $message) = @_;
         
                        $client->send_message(...);
                    }
                );

                $client->on_message(
                    sub {
                        my ($client, $message) = @_;

                        ...
                        $vnc->pointer_event($message->{x},
                                $message->{y}, $mask);
                        ...
                    }
                );
            }
        );

        $server->listen;

Crear una conexión esclava enlazada a un WebSocket es muy sencillo. Sólo registras los callbacks apropiados y Perl se encarga de grabar el contexto. Cada vez que algo viene desde el navegador se pasa a VNC, y viceversa, sin necesidad de controlar las conexiones tú mismo. Y, desde el lado del cliente, el dibujado se realiza usando el canvas de HTML5. Es bastante fácil crear tus propias imágenes, copiar rectángulos,etc. Para capturar el teclado y el ratón el autor aconseja usar jQuery.

Más información | Código fuente de showmethedesktop Via | Artículo original en showmetheco.de

Portada de Genbeta