Categorías: Labs

La API de BroadcastChannel en Firefox 38

Esta es una traducción del artículo original publicado en el blog de Mozilla Hacks.

Recientemente la API de BroadcastChannel llegó a Firefox 38. Esta API puede ser usada para el envío sencillo de mensajes entre navegadores que tienen el mismo agente de usuario y origen. Esta API es expuesta a ambos Windows y Workers y permite la comunicación entre iframes, pestañas de navegador e hilos.

La intención de la API de BroadcastChannel es proveer una API que facilite la comunicación simple de mensajes entre contextos de navegador con una aplicación web. Por ejemplo, cuando un usuario inicia sesión en una página web de una aplicación, esta puede actualizar todos los otros contextos (como pestañas o ventanas separadas) con la información del usuario, o si un usuario sube una foto a una ventana del navegador, la imagen puede ser pasada a las otras páginas dentro de la aplicación. Esta API no tiene la intención de manejar operaciones complejas como bloqueo de recursos compartidos o sincronización de múltiples clientes con un servidor. En estos casos, un worker compartido es más apropiado.

Resumen de la API

Un objeto BroadcastChannel puede ser creado usando el siguiente código.

var myChannel = new BroadcastChannel("channelname");

El channelname distingue mayúsculas y minúsculas. La instancia de BroadcastChannel contiene dos métodos. postMessage y close. El método postMessage es usado para enviar mensajes al canal. El contenido del mensaje puede ser cualquier objeto, incluyendo objetos complejos como imágenes, arrays u objetos. Cuando el mensaje es enviado, todos los contextos del navegador con el mismo origen, agente de usuario y un BroadcastChannel con el mismo nombre de canal son notificados del mensaje. Por ejemplo, el siguiente código envía una simple cadena de texto:

myChannel.postMessage("Mensaje sencillo");

Le mensaje enviado puede ser manejado por cualquier página con el canal abierto usando el manejador del evento onmessage de la instancia de BroadcastChannel.

myChannel.onmessage = function (event) {
    console.log(event.data);
};

Ten en cuenta que el atributo data de event contiene los datos del mensaje. Los otros atributos de event pueden ser interesantes también. Por ejemplo, puedes verificar el origen de la aplicación web usando el atributo event.origin o si el nombre del canal está disponible con el atributo event.target.name.

El método close es usado para cerrar el canal para un contexto de navegador en particular y puede ser llamado usando simplemente:

broadCastChannel.close();

Enviando mensajes Blob

Mientras que enviar cadenas de texto y otros tipos primitivos de datos es bastante simple, la API de BroadcastChannel soporta objetos más complejos. Por ejemplo, para enviar un objeto Image desde un contexto a otro, puede ser usado el siguiente código.

var broadcastExample = {};
broadcastExample.setupChannel = function() {
    if ("BroadcastChannel" in window) {
        if (typeof broadcastExample.channel === 'undefined' || !broadcastExample.channel) {
            //crear el canal
            broadcastExample.channel = new BroadcastChannel("foo");
        }
    }
}
 
broadcastExample.pMessage = function() {
    broadcastExample.setupChannel();
    //obtener el elemento image
    var img = document.getElementById("ffimg");
    //crear un canvas con la imagen
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    //obtener blob desde canvas
    canvas.toBlob(function(blob) {
        //enviar blob ví broadcast
        broadcastExample.channel.postMessage(blob);
    });
}

El código anterior contiene dos funciones y representa el lado emisor de un cliente BroadcastChannel. El método setupChannel sólo abre un canal Broadcast y el método pMessage recibe un elemento Image desde la página y la convierte a Blob. Luego, el blob es enviado al BroadcastChannel. La página receptora necesitará estar escuchando al BroadcastChannel para poder recibir el mensaje, puede ser programado de la siguiente forma.

var broadcastFrame = {};
 
//establecer el canal del broadcast
broadcastFrame.setup = function() {
    if ("BroadcastChannel" in window) {
        if (typeof broadcastFrame.channel === 'undefined' || !broadcastFrame.channel) {
            broadcastFrame.channel = new BroadcastChannel("foo");
        }
        //función para procesar mesages del broadcast
        function func(e) {
            if (e.data instanceof Blob) {
                //si el mensaje es un blob, crear un elemento image y agregarlo a la página
                var blob = e.data;
                var newImg = document.createElement("img"),
                    url = URL.createObjectURL(blob);
                newImg.onload = function() {
                    //ya no se necesita leer el blob así que es anulado
                    URL.revokeObjectURL(url);
                };
                newImg.src = url;
                var content = document.getElementById("content");
                content.innerHTML = "";
                content.appendChild(newImg);
            }
        };
        //establecer el manejador de mensajes del canal del broadcast
        broadcastFrame.channel.onmessage = func;
    }
}
window.onload = broadcastFrame.setup();

Este  código toma el blob desde el mensaje del broadcast y crea un elemento Image que es agregado a la página receptora.

Workers y mensajes de BroadcastChannel

La API de BroadcastChannel también funciona con workers dedicados y compartidos. Como un simple ejemplo, imagina que un worker es iniciado y cuando un mensaje es enviado al worker a través del script principal, el worker luego envía un mensaje al Broadcast Channel.

var broadcastExample = {};
broadcastExample.setupChannel = function() {
    if ("BroadcastChannel" in window) {
        if (typeof broadcastExample.channel === 'undefined' ||  !broadcastExample.channel) {
            //crear un canal
            broadcastExample.channel = new BroadcastChannel("foo");
        }
    }
}
 
function callWorker() {
    broadcastExample.setupChannel();
    //verificar compatibilidad
    if (!!window.Worker) {
        var myWorker = new Worker("worker.js");
        //conectar el worker para enviar al Canal de Broadcast
        myWorker.postMessage("Broadcast from Worker");
    }
}
 
//Worker.js
onmessage = function(e) {
    //enviar mensaje del canal del Broadcast con el Worker
    if ("BroadcastChannel" in this) {
        var workerChannel = new BroadcastChannel("foo");
        workerChannel.postMessage("BroadcastChannel Message Sent from Worker");
        workerChannel.close();
    }
};

El mensaje puede ser manejado en la página principal de la misma forma descrita en las anteriores secciones de este artículo.

Usando un Worker para enviar un mensaje por Broadcast a un iframe

Usando un Worker para enviar un mensaje por Broadcast a un iframe

Más información

Además de demostrar como usarlo en un iframe, otro ejemplo de uso del código de este artículo está disponible en GitHub. Más información sobre la API de BroadcastChannel está disponible en la especificación, en BugZilla y en la MDN. El código y páginas de pruebas para la API está localizadas en el código fuente de Gecko.

The following two tabs change content below.

AngelFQC

Web Developer at BeezNest Latino
Ingeniero de Sistemas y Computación. Desarrollador PHP. Mozilla Peru. Chamilo LMS Developer.