Silverlight 3 Beta 1: Conexión Local

Nota: Este artículo ha sido reemplazado por este otro:

https://rdiazconcha.com/2010/06/silverlight-4-conexin-local/

Introducción

Nuevo en Silverlight 3 tenemos una nueva característica que permite comunicarnos entre diferentes aplicaciones dentro de la misma máquina.  Esta característica está bautizada como Conexión Local (Local Connection en inglés).  Si bien en Silverlight 2 tenemos la posibilidad de comunicarnos entre diferentes aplicaciones dentro de la misma página no es una tarea trivial; además tratar de hacerlo entre diferentes instancias de navegadores es prácticamente un infierno.

Esta nueva funcionalidad nos ofrece un mecanismo poderoso para poder complementar nuestros aplicativos que requieran tener comunicación entre sí, ya que implementar esta característica es bastante sencillo como lo demostraremos en este artículo.

System.Windows.Messaging

Todas las clases necesarias para la implementación de la conexión local entre aplicaciones están incluidas en el espacio de nombres System.Windows.Messaging

Clase LocalMessageSender

Esta clase permite el envío de mensajes a un receptor por medio del nombre especificado.  Además permite establecer el nombre del dominio en el que se encuentra el receptor.  Incluye el método SendAsync() el cual enviará el mensaje de manera asíncrona al receptor.  Una vez enviado el mensaje se disparará el evento SendCompleted, el cual incluye en sus argumentos la propiedad Error la cual nos indica si sucedió una excepción durante el envío del mensaje.

Clase LocalMessageReceiver

Análoga a la clase LocalMessageSender, esta clase nos permite recibir mensajes.  También aquí establecemos el nombre del receptor, que deberá concordar con el nombre establecido en el objeto de tipo LocalMessageSender.  Una vez recibido un mensaje se dispara el evento MessageReceived el cual incluye en sus argumentos la propiedad Message de tipo string, misma que contiene el mensaje enviado por la aplicación origen.

Además de esto podemos especificar los dominios válidos de los que puede recibir mensajes este objeto!

Modelo Publicador-Subscriptor

Es a través de este modelo publicador-subscriptor por el cual podemos implementar comunicación entre diferentes aplicaciones de Silverlight 3 en la misma página, o en diferentes pestañas del Navegador… incluso entre diferentes instancias de Navegadores, INCLUSO entre diferentes tipos de Navegadores (IE, FF, GC, etc.!).

Es importante mencionar además que una aplicación de Silverlight no está limitada a ser únicamente publicador o subscriptor, sino que puede ser ambos!  Esto es, podemos establecer una comunicación local bidireccional entre aplicaciones.  El único requisito es tener los objetos LocalMessageSender y LocalMessageReceiver en cada aplicación de manera correcta.

La Solución

La solución que crearemos estará compuesta de dos aplicaciones Silverlight.  La aplicación Origen permitirá la captura de contenido Xaml dentro de un TextBox e incluirá un botón para enviar el Xaml a la aplicación Destino.

La aplicación Destino por su parte estará escuchando nuevos mensajes que le envíe la aplicación Origen.  Cuando llegue efectivamente un mensaje, interpretará el Xaml convirtiendo todo el árbol de contenido en los elementos visuales correspondientes al código, y los dibujará dentro de un Grid llamado LayoutRoot.

Ambos proyectos de Silverlight estarán contenidos en una misma solución, la cual también incluirá una Aplicación Web para poder probar la funcionalidad.  Además ambos proyectos estarán relacionados a la misma Aplicación Web para que nos cree automáticamente las páginas de prueba.  La siguiente figura muestra la estructura de la solución:


Origen

La aplicación Origen contiene un TextBox para escribir una cadena de Xaml válida que se enviará al destino.  Además contiene un botón que hará efectivamente el envío del mensaje.  El siguiente fragmento de código muestra la implementación de la aplicación Origen:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Messaging;

namespace SL3ConexionLocal.Origen
{
    public partial class MainPage : UserControl
    {
        LocalMessageSender sender;
        public MainPage()
        {
            InitializeComponent();

            sender = new LocalMessageSender("SL3ConexionLocal");

            SendXamlButton.Click += (s, a) =>
            {
                sender.SendAsync(XamlTextBox.Text);
            };

            sender.SendCompleted += (s, a) =>
            {
                if (a.Error != null)
                {
                    MessageBox.Show(a.Error.Message);
                }
            };

        }

    }
}
Destino

La aplicación Destino recibirá el mensaje enviado por el Origen:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Messaging;
using System.Windows.Markup;

namespace SL3ConexionLocal.Destino
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            //Receptor/Receiver
            //Podemos especificar los dominios válidos de los que podrás recibir mensajes!
            //We can specify the domains where this object can receive messages from!

            LocalMessageReceiver receiver = new LocalMessageReceiver("SL3ConexionLocal");
            receiver.MessageReceived += (s, a) =>
            {
                string message = a.Message;
                try
                {
                    UIElement newContent = (UIElement)XamlReader.Load(message);

                    LayoutRoot.Children.Clear();
                    LayoutRoot.Children.Add(newContent);
                }
                catch (Exception)
                {
                    MessageBox.Show("No es un Xaml válido");
                }

            };
            receiver.Listen();
        }
    }
}

Noten cómo se establece el nombre del receptor como “SL3ConexionLocal”.  Posteriormente se comienza a escuchar por mensajes usando el método Listen() y cuando uno es recibido efectivamente se interpreta a un objeto de tipo UIElement a través del método XamlReader.Load().

Al ejecutar la aplicación Origen en un Navegador y la aplicación Destino en otro (usando las páginas de prueba creadas automáticamente para cada aplicación) podemos comprobar esta funcionalidad:

El siguiente ScreenCast muestra la solución construida en este artículo ejecutándose incluso usando un segundo publicador (aplicación Origen corriendo en FireFox).  También es notable el uso de tres diferentes tecnologías de Navegadores lo cual muestra la capacidad que tiene Silverlight para ejecutarse en múltiples ambientes.

Silverlight 3 – Conexión Local

Resumen

La Conexión Local incorporada en Silverlight 3 permite comunicarnos de una aplicación a otra a través de un mecanismo de publicación-subscripción.  Esta interesante y poderosa funcionalidad abre nuevos paradigmas en el desarrollo de aplicaciones RIA, ya que su modelo de programación es bastante sencillo y sus alcances en soluciones con Silverlight son innumerables.