Actividades de mensajería

Las actividades de mensajería permiten a los flujos de trabajo enviar y recibir mensajes de WCF. Al agregar actividades de mensajería a un flujo de trabajo, puede modelar cualquier patrón de intercambio de mensajes (MEP) arbitrariamente complejo.

Patrones de intercambio de mensajes

Hay tres patrones de intercambio de mensajes básicos:

  • Datagrama: cuando se usa el datagrama MEP, el cliente envía un mensaje al servicio, pero el servicio no responde. Esto se llama a veces "fire and forget" (dispare y olvídese). Un intercambio de este tipo es uno que exige una confirmación fuera de banda de entrega correcta. El mensaje se podría perderse por el camino y no llegar nunca al servicio. El hecho de que el cliente envíe un mensaje correctamente no garantiza que el servicio haya recibido el mensaje. El datagrama es una unidad de creación fundamental para la mensajería, ya que puede compilar sus propios MEP sobre él.

  • Request-Response: cuando se usa el MEP de solicitud-respuesta, el cliente envía un mensaje al servicio, el servicio realiza el procesamiento necesario y, a continuación, envía una respuesta al cliente. El patrón está compuesto de los pares solicitud-respuesta. Los ejemplos de llamadas de solicitud-respuesta son llamadas a procedimientos remotos (RPC) y solicitudes GET del explorador. Este patrón también se conoce como dúplex medio.

  • Duplex: cuando se usa el MEP dúplex, el cliente y el servicio pueden enviar mensajes entre sí en cualquier orden. El MEP de dúplex es como una conversación telefónica, donde cada palabra que se pronuncia es un mensaje.

Las actividades de mensajería le permiten implementar cualquiera de estos MEP básicos, así como cualquier MEP arbitrariamente complejo.

Actividades de mensajería

.NET Framework 4.6.1 define las siguientes actividades de mensajería:

  • Send: Use la actividad Send para enviar un mensaje.

  • SendReply: Utilice la actividad SendReply para enviar una respuesta a un mensaje recibido. Esta actividad la emplean los servicios de flujo de trabajo al implementar un MEP de solicitud/respuesta.

  • Receive: Use la actividad Receive para recibir un mensaje.

  • ReceiveReply: Use la actividad ReceiveReply para recibir un mensaje de respuesta. Esta actividad la emplean los clientes de servicios de flujo de trabajo al implementar un MEP de solicitud/respuesta.

Actividades de mensajería y patrones de intercambio de mensajes

Un MEP de datagrama implica que un cliente envía un mensaje y un servicio recibe el mensaje. Si el cliente es un uso del flujo de trabajo, use una actividad Send para enviar el mensaje. Para recibir ese mensaje en un flujo de trabajo, use una actividad Receive. Cada una de las actividades Send y Receive tiene una propiedad denominada Content. Esta propiedad contiene los datos que se envían o se reciben. Al implementar el MEP de solicitud-respuesta, tanto el cliente como el servicio usan pares de actividades. El cliente usa una actividad Send para enviar al mensaje y a una actividad ReceiveReply para recibir la respuesta del servicio. La propiedad Request asocia entre sí estas dos actividades. Esta propiedad está establecida en la actividad Send que envió el mensaje original. El servicio también usa un par de actividades asociadas: Receive y SendReply. La propiedad Request asocia estas dos actividades. Esta propiedad está establecida en la actividad Receive que recibió el mensaje original. Las actividades ReceiveReply y SendReply, como Send y Receive, le permiten enviar una instancia Message o un tipo de contrato de mensaje.

Debido a la naturaleza de ejecución prolongada de los flujos de trabajo, es importante que el patrón dúplex de comunicación también admita las conversaciones de ejecución prolongada. Para admitir conversaciones de ejecución prolongada, los clientes que inician la conversación deben proporcionar el servicio con una oportunidad de volver a llamarlo posteriormente cuando los datos estén disponibles. Por ejemplo, se envía una solicitud de pedido de compra para la aprobación del administrador, pero podría no procesarse durante un día, una semana, o incluso un año; el flujo de trabajo que administra la aprobación del pedido de compra debe saber reanudar una vez otorgada la aprobación. Este patrón de comunicación dúplex se admite en flujos de trabajo que usan correlación. Para implementar un patrón dúplex, use las actividades Send y Receive. En la actividad Receive, inicialice una correlación mediante CorrelationHandle. En la actividad Send, establezca ese controlador de correlación como valor de propiedad CorrelatesWith. Para obtener más información, consulte Dúplex duradero.

Nota

La implementación del flujo de trabajo de dúplex mediante una correlación de devolución de llamada ("dúplex duradero") está pensada para conversaciones de larga ejecución. Esto no es igual que el dúplex de WCF con contratos de devolución de llamada, donde la conversación es de ejecución reducida (la duración del canal).

Formato de mensajes y actividades de mensajería

Las actividades Receive y ReceiveReply tienen una propiedad denominada Content. Esta propiedad es del tipo ReceiveContent y representa los datos que recibe la actividad Receive o ReceiveReply. El sistema .NET Framework define dos clases relacionadas denominadas ReceiveMessageContent y ReceiveParametersContent, que se derivan de ReceiveContent. Establezca la propiedad Receive de la actividad ReceiveReply o Content en una instancia de uno de estos tipos para recibir datos en un servicio de flujo de trabajo. El tipo que se va a usar depende del tipo de datos que recibe la actividad. Si la actividad recibe un objeto Message o un tipo de contrato de mensaje, use ReceiveMessageContent. Si la actividad recibe un conjunto de contrato de datos o tipos de XML que se puede serializar, use ReceiveParametersContent. ReceiveParametersContent le permite enviar varios parámetros, mientras que ReceiveMessageContent solo permite enviar un objeto, el mensaje (o tipo de contrato de mensaje).

Nota

ReceiveMessageContent también se puede utilizar con un contrato de datos único o un tipo de XML que se puede serializar. La diferencia entre utilizar la clase ReceiveParametersContent con un parámetro único y el objeto pasado directamente a ReceiveMessageContent es el formato de conexión. El contenido del parámetro se ajusta en un elemento XML que corresponde al nombre de la operación, y el objeto serializado se ajusta en un elemento XML mediante el nombre de parámetro (por ejemplo, <Echo><msg>Hello, World</msg></Echo>). El nombre de la operación no ajusta el contenido del mensaje. En su lugar, el objeto serializado se coloca dentro de un elemento XML mediante el nombre de tipo XML completo (por ejemplo, <string>Hello, World</string>).

Las actividades Send y SendReply también tienen una propiedad denominada Content. Esta propiedad es del tipo SendContent y representa datos que envía la actividad Send o SendReply. El sistema .NET Framework define dos tipos relacionados denominados SendMessageContent y SendParametersContent, que se derivan de SendContent. Establezca la propiedad Send de la actividad SendReply o Content en una instancia de uno de estos tipos para enviar datos de un servicio de flujo de trabajo. El tipo que se va a usar depende del tipo de datos que envía la actividad. Si la actividad envía un objeto Message o un tipo de contrato de mensaje, use SendMessageContent. Si la actividad envía un tipo de contrato de datos, use SendParametersContent. SendParametersContent le permite enviar varios parámetros, mientras que SendMessageContent solo permite enviar un objeto, el mensaje (o tipo de contrato de mensaje).

Al programar imperiosamente con las actividades de mensajería, use InArgument<T> y OutArgument<T> de forma genérica para ajustar los objetos asignados al mensaje o las propiedades de parámetros de las actividades Send, SendReply, Receive y ReceiveReply. Use InArgument<T> para Send y las actividades SendReply y OutArgument<T> para las actividades Receive y ReceiveReply. Los argumentos In se usan con las actividades de envío porque los datos se pasan a las actividades. Los argumentos Out se usan con las actividades de recepción porque se pasan datos de las actividades, como se muestra en el ejemplo siguiente.

Receive reserveSeat = new Receive
{
    ...
    Content = new ReceiveParametersContent
    {
        Parameters =
        {
            { "ReservationInfo", new OutArgument<ReservationRequest>(reservationInfo) }
        }
    }
};
SendReply reserveSeat = new SendReply
{
    ...
    Request = reserveSeat,
    Content = new SendParametersContent
    {
        Parameters =
        {
            { "ReservationId", new InArgument<string>(reservationId) }
        }
    },
};

Al implementar un servicio de flujo de trabajo que define una operación de solicitud/respuesta que devuelve un valor nulo, debe crear instancias de una actividad SendReply y establecer la propiedad Content en una instancia vacía de uno de los tipos de contenido (SendMessageContent o SendParametersContent), tal y como se muestra en el siguiente ejemplo.

Receive rcv = new Receive()
{
ServiceContractName = "IService",
OperationName = "NullReturningContract",
Content = new ReceiveParametersContent( new Dictionary<string, OutArgument>() { { "message", new OutArgument<string>() } } )
};
SendReply sr = new SendReply()
{
Request = rcv
   Content = new SendParametersContent();
};

Agregue la referencia de servicio

Al llamar a un servicio de flujo de trabajo desde una aplicación de flujo de trabajo, Visual Studio 2012 genera actividades de mensajería personalizadas que encapsulan las actividades Send y ReceiveReply habituales que se usan en un MEP de solicitud-respuesta. Para usar esta característica, haga clic con el botón derecho en el proyecto de cliente en Visual Studio 2010 y seleccione Agregar>referencia de servicio. Escriba la dirección base del servicio en el cuadro de dirección y haga clic en Ir. Los servicios disponibles se muestran en el cuadro Servicios: . Expanda el nodo de servicio para mostrar los contratos admitidos. Seleccione el contrato al que quiere llamar para mostrar la lista de operaciones disponibles en el cuadro Operaciones. A continuación, puede especificar el espacio de nombres para la actividad generada y hacer clic en Aceptar. A continuación, verá un cuadro de diálogo que dice que la operación se ha completado correctamente y que las actividades personalizadas generadas se encontrarán en el cuadro de herramientas tras haber recompilado el proyecto. Hay una actividad para cada operación definida en el contrato de servicios. Después de recompilar el proyecto, puede arrastrar y colocar las actividades personalizadas en el flujo de trabajo y establecer cualquier propiedad necesaria en la ventana Propiedades.

Plantillas de actividades de mensajería

Para simplificar la configuración de un MEP de solicitud-respuesta en el cliente y el servicio, Visual Studio 2012 proporciona dos plantillas de actividad de mensajería. System.ServiceModel.Activities.Design.ReceiveAndSendReply se usa en el servicio y System.ServiceModel.Activities.Design.SendAndReceiveReply se usa en el cliente. En ambos casos, las plantillas agregan las actividades de mensajería adecuadas al flujo de trabajo. En el servicio, System.ServiceModel.Activities.Design.ReceiveAndSendReply agrega una actividad Receive seguida por una actividad SendReply. La propiedad Request se establece en la actividad Receive de forma automática. En el cliente, System.ServiceModel.Activities.Design.SendAndReceiveReply agrega una actividad Send seguida por ReceiveReply. La propiedad Request se establece en la actividad Send de forma automática. Para utilizar estas plantillas, simplemente arrastre y coloque la plantilla adecuada en el flujo de trabajo.

Actividades de mensajería y transacciones

Cuando se realiza una llamada a un servicio de flujo de trabajo, puede desear hacer fluir una transacción a una operación del servicio. Para ello, coloque la actividad Receive dentro de una actividad TransactedReceiveScope. La actividad TransactedReceiveScope contiene una actividad Receive y un cuerpo. La transacción que ha fluido al servicio permanece ambiente a lo largo de la ejecución del cuerpo de TransactedReceiveScope. Se completa la transacción cuando el cuerpo termina de ejecutarse. Para obtener más información sobre los flujos de trabajo y las transacciones, consulte Transacciones de flujo de trabajo.

Consulte también