Exportar (0) Imprimir
Expandir todo

NetMessagingBinding

Actualizado: marzo de 2014

La mensajería asincrónica de Service Bus admite el modelo de programación WCF y proporciona un nuevo enlace denominado NetMessagingBinding que pueden usar las aplicaciones habilitadas para WCF para enviar y recibir mensajes a través de las colas, los temas y las suscripciones. NetMessagingBinding es el nuevo nombre del enlace de las colas y los temas que proporciona una integración completa con WCF. Desde una perspectiva funcional, NetMessagingBinding es similar a NetMsmqBinding, que permite poner en cola mediante Message Queuing (MSMQ) como transporte y habilita la compatibilidad con aplicaciones de acoplamiento flexible. En lo que respecta a servicio, NetMessagingBinding proporciona un bombeo automático de mensajes que extrae de una cola o una suscripción, y se integra con el mecanismo ReceiveContext de WCF.

El nuevo enlace admite las interfaces estándar IInputChannel, IOutputChannel e IInputSessionChannel. Cuando una aplicación utiliza WCF y NetMessagingBinding para enviar un mensaje a una cola o un tema, el mensaje se ajusta y se codifica en un elemento Envelope de SOAP. Para establecer las propiedades específicas de BrokeredMessage, debe crear un objeto BrokeredMessageProperty, establecer las propiedades correspondientes y agregarlo a la colección Properties del mensaje WCF, como se muestra en el siguiente ejemplo. Cuando se utiliza NetMessagingBinding para escribir un mensaje en una cola o en un tema, la clase interna ServiceBusOutputChannel busca la propiedad BrokeredMessageProperty en la colección Properties del mensaje WCF y copia todas sus propiedades al objeto BrokeredMessage que crea. Después, copia la carga del mensaje WCF en el objeto BrokeredMessage y, por último, publica el mensaje resultante en el tema o la cola de destino.

static void Main(string[] args)
{
    try
    {
        // Create the 
        var channelFactory = new ChannelFactory<IOrderService>("orderEndpoint");
        var clientChannel = channelFactory.CreateChannel();
        
        // Create a order object
        var order = new Order()
                        {
                            ItemId = "001",
                            Quantity = 10
                        };

        // Use the OperationContextScope to create a block within which to access the current OperationScope
        using (var scope = new OperationContextScope((IContextChannel)clientChannel))
        {
            // Create a new BrokeredMessageProperty object
            var property = new BrokeredMessageProperty();

            // Use the BrokeredMessageProperty object to set the BrokeredMessage properties
            property.Label = "OrderItem";
            property.MessageId = Guid.NewGuid().ToString();
            property.ReplyTo = "sb://acme.servicebus.windows.net/invoicequeue";

            // Use the BrokeredMessageProperty object to define application-specific properties
            property.Properties.Add("ShipCountry", "Italy");
            property.Properties.Add("ShipCity", "Milan");

            // Add BrokeredMessageProperty to the OutgoingMessageProperties bag provided 
            // by the current Operation Context 
            OperationContext.Current.OutgoingMessageProperties.Add(BrokeredMessageProperty.Name, property);
            clientChannel.SendOrder(order);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Asimismo, cuando utiliza un extremo de servicio basado en NetMessagingBinding para recibir los mensajes de una cola o un tema, una aplicación puede recuperar el objeto BrokeredMessageProperty de la colección Properties del mensaje WCF entrante, como se muestra en el siguiente ejemplo. En particular, cuando el extremo de servicio recibe mensajes, las clases internas ServiceBusInputChannel y ServiceBusInputSessionChannel crean un mensaje WCF nuevo y copian la carga del cuerpo del entrante en el cuerpo del mensaje WCF recientemente creado. (ServiceBusInputSessionChannel se utiliza para recibir mensajes de colas y suscripciones con sesión). A continuación, copian las propiedades del BrokeredMessage entrante en una nueva instancia de la clase BrokeredMessageProperty y, finalmente, agregan el nuevo objeto BrokeredMessageProperty a la colección Properties del mensaje WCF entrante.

[ServiceBehavior]
public class OrderService : IOrderService
{
    [OperationBehavior]
    public void ReceiveOrder(Order order)
    {
        // Get the BrokeredMessageProperty from the current OperationContext
        var incomingProperties = OperationContext.Current.IncomingMessageProperties;
        var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;

        ...
    }
}

Dado que Service Bus no admite la interfaz IInputSessionChannel, todas las aplicaciones que envían mensajes a colas habilitadas para sesión deben usar un contrato de servicio donde el valor de la propiedad SessionMode sea diferente de la de SessionMode.Required. Sin embargo, dado que el tiempo de ejecución de WCF de Service Bus admite la interfaz IInputSessionChannel y otras interfaces para recibir los mensajes de una suscripción o una cola con sesión que usa WCF y NetMessagingBinding, las aplicaciones deben implementar un contrato de servicio compatible con sesiones. El fragmento de código siguiente proporciona un ejemplo de un servicio WCF que recibe mensajes de una cola o suscripción con sesión.

// ServiceBus does not support IOutputSessionChannel.
// All senders sending messages to sessionful queue must use a contract which does not enforce SessionMode.Required.
// Sessionful messages are sent by setting the SessionId property of the BrokeredMessageProperty object.
[ServiceContract]
public interface IOrderService
{
    [OperationContract(IsOneWay = true)]
    [ReceiveContextEnabled(ManualControl = true)]
    void ReceiveOrder(Order order);
}

// ServiceBus supports both IInputChannel and IInputSessionChannel. 
// A sessionful service listening to a sessionful queue must have SessionMode.Required in its contract.
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IOrderServiceSessionful : IOrderService
{
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
public class OrderService : IOrderServiceSessionful
{
    [OperationBehavior]
    public void ReceiveOrder(Order order)
    {
        // Get the BrokeredMessageProperty from the current OperationContext
        var incomingProperties = OperationContext.Current.IncomingMessageProperties;
        var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;

        ...

        //Complete the Message
        ReceiveContext receiveContext;
        if (ReceiveContext.TryGet(incomingProperties, out receiveContext))
        {
            receiveContext.Complete(TimeSpan.FromSeconds(10.0d));
            ...
        }
        else
        {
            throw new InvalidOperationException("...");
        }
    }
}

Observe que la propiedad ManualControl del atributo de operación ReceiveContextEnabled está establecida en true. Esta configuración hace que el servicio invoque explícitamente al método ReceiveContext.Complete para confirmar la operación de recepción. De hecho, cuando la propiedad ManualControl está establecida en true, el mensaje recibido del canal se entrega a la operación de servicio con un bloqueo. La implementación del servicio debe invocar Complete(TimeSpan) o Abandon(TimeSpan) para indicar que el mensaje se ha recibido completamente. Si no se puede invocar uno de estos métodos, el bloqueo se mantiene en el mensaje hasta que transcurre el intervalo de tiempo de espera. Una vez que se libera el bloqueo (ya sea al invocar Abandon(TimeSpan) o porque transcurre el tiempo de espera), el mensaje se vuelve a enviar desde el canal al servicio. Al llamar a Complete(TimeSpan), se marca el mensaje como que se ha recibido correctamente.

Observe también que la clase OrderService establece la propiedad ServiceBehavior.InstanceContextMode en InstanceContextMode.PerSession y la propiedad ConcurrencyMode en ConcurrencyMode.Single. De este modo, ServiceHost crea una nueva instancia de servicio cada vez que hay una nueva sesión disponible en la cola o suscripción específica, y ServiceHost utiliza un solo subproceso para recibir mensajes en secuencia desde la cola o suscripción. La propiedad SessionIdleTimeout de NetMessagingBinding controla la duración del servicio. Para obtener más información sobre cómo usar los mensajes de intercambio WCF mediante una cola con sesión, le recomiendo que observe el modelo WcfServiceSessionSample que se incluye en la Windows Azure AppFabric SDK V1.5.

Adiciones de comunidad

Mostrar:
© 2014 Microsoft