Adicionar Headers en Mensajes SOAP

Para diferentes efectos (enrutamiento por ejemplo) es necesario agregar a los mensajes SOAP gestionados por servicios de WCF un encabezado (header) personalizado con información, de esta forma se puede enviar información entre los clientes y los servicios sin que sea necesario modificar el contenido del servicio (datos). Un recordatorio rápido de cómo hacerlo usando código en WCF 3.5.

 

 

ServicioFuncionario.ServicioFuncionarioClient sv = new ServicioFuncionario.ServicioFuncionarioClient();
using (new OperationContextScope(sv.InnerChannel))
{
     MessageHeader headerLocal = MessageHeader.CreateHeader("Key", "http://serviciosproduccionCP", "HostCP");
     OperationContext.Current.OutgoingMessageHeaders.Add(headerLocal);

     MessageHeader headerBogota = MessageHeader.CreateHeader("Key", "http://serviciosproduccionBogota", "HostBogota");
     OperationContext.Current.OutgoingMessageHeaders.Add(headerBogota);

     resultado = sv.FuncionarioLogin(login, passWord);
}

sv.Close();

Este código agrega dos encabezados a la petición funcionarioLogin, el valor HostCP y HostBogota es el que nos interesa agregar a los mensajes, con esa información el servicio podría realizar diferentes procesos como enrutamiento, registro, gestión de errores, respaldo entre otros.

 

Nota1: en WCF 4.0 se puede utilizar el tag header en el archivo de configuración del servicio.

Nota2: El protocolo usado en la comunicación debe tener soporte para la gestión de encabezados en el mensaje SOAP.

 

 

Juan Peláez

3Metas Corp

Multicast with WCF 3.5

Para escenarios de Arquitecturas Distribuidas con Multicast usando WCF 3.5 una opción posible es la siguiente:

[ServiceContract(Namespace = "http://servicios.cliente/2009/06", Name = "IRouter")]
public interface IServiceRouter
{
   [OperationContract(ReplyAction = "*", Action = "*")]
   Message ForwardMessage(Message message);
}

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
class ServiceRouter : IServiceRouter
{
               
        #region IRouter Members
 
        public Message ForwardMessage(Message message)
        {
            Message BogotaServer;
            Message localServer;
 
            MessageBuffer messageBuffer = message.CreateBufferedCopy(int.MaxValue);
            Message messageCopy = messageBuffer.CreateMessage();
            Message messageCopy2 = messageBuffer.CreateMessage();
 
 
            //Almacenamiento en servidor local finca   
            int headerLocalIndex = message.Headers.FindHeader("Key", "http://serviciosproduccionCP");
            if (headerLocalIndex != -1)
            {
                string localHost = message.Headers.GetHeader<string>(headerLocalIndex);
                ChannelFactory<IServiceRouter> client = new ChannelFactory<IServiceRouter>(localHost);
                localServer = (client.CreateChannel()).ForwardMessage(messageCopy);
            }
            else
            {
                throw new InvalidOperationException("No se puede encontrar la cabecera 'local'");
            }
 
            //Almacenamiento en servidor de Bogotá.  
            int headerBogotaIndex = message.Headers.FindHeader("Key", "http://serviciosproduccionBogota");
            if (headerBogotaIndex != -1)
            {
                string bogotaHost = message.Headers.GetHeader<string>(headerBogotaIndex);
                ChannelFactory<IServiceRouter> client = new ChannelFactory<IServiceRouter>(bogotaHost);
                BogotaServer = (client.CreateChannel()).ForwardMessage(messageCopy2);
            }
            else
            {
                throw new InvalidOperationException("No se puede encontrar la cabecera 'bogota'");
            }
 
            return BogotaServer; 
 
        }
 
        #endregion
    }
 

Este código analiza la información enviada por el cliente y crea una copia del mensaje que es distribuido posteriormente a los servidores que estén registrados en el encabezado del mensaje. Esta técnica de enrutamiento se basa en Contenido, el contenido del header del mensaje SOAP.

 

 

Juan Peláez

3Metas Corp.