Compartir por


Elección de un patrón de intercambio de mensajes

El primer paso a la hora de escribir un transporte personalizado es decidir qué patrones de intercambio de mensajes (o MEP) son necesarios para el canal que está desarrollando. En este tema se describen las opciones disponibles y se describen los distintos requisitos. Esta es la primera tarea de la lista de tareas de desarrollo del canal que se describe en Desarrollo de canales.

Seis patrones de intercambio de mensajes

Hay tres DIPUTADOs entre los que elegir:

  • Datagram (IInputChannel y IOutputChannel)

    Al utilizar un MEP de datagrama, un cliente envía un mensaje mediante un intercambio de tipo desencadenar y omitir. Un intercambio de este tipo es uno que exige una confirmación fuera de banda de entrega correcta. Es posible que el mensaje se pierda en tránsito y nunca llegue al servicio. Si la operación de envío se completa correctamente en el lado del cliente, no garantiza que el punto de conexión remoto haya recibido el mensaje. El datagrama es un bloque de creación fundamental para la mensajería, ya que puede crear sus propios protocolos sobre él, incluidos protocolos confiables y protocolos seguros. Los canales de datagrama de cliente implementan la interfaz IOutputChannel y los canales de datagrama de servicio implementan la interfaz IInputChannel.

  • Request-Response (IRequestChannel y IReplyChannel)

    En este MEP, se envía un mensaje y se recibe una respuesta. El patrón consta de pares de solicitud-respuesta. Algunos 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. En este MEP, los canales de cliente implementan IRequestChannel y los canales de servicio implementan IReplyChannel.

  • Dúplex (IDuplexChannel)

    El MEP dúplex permite que un cliente envíe un número arbitrario de mensajes y los reciba en cualquier orden. El MEP de dúplex es como una conversación telefónica, donde cada palabra que se pronuncia es un mensaje. Dado que ambos lados pueden enviar y recibir en este MEP, la interfaz implementada por los canales de cliente y servicio es IDuplexChannel.

Diagrama de flujo que muestra los tres patrones básicos de intercambio de mensajes
Los tres patrones básicos de intercambio de mensajes. De arriba abajo: datagrama, solicitud-respuesta y dúplex.

Cada uno de estos MEP también puede admitir sesiones. Una sesión (e implementación de System.ServiceModel.Channels.ISessionChannel<TSession> de tipo System.ServiceModel.Channels.ISession) pone en correlación todos los mensajes enviados y recibidos en un canal. El patrón request-response es una sesión independiente de dos mensajes, ya que la solicitud y la respuesta se correlacionan. Por el contrario, el patrón de solicitud-respuesta que admite las sesiones implica que se ponen en correlación todos los pares de solicitud/respuesta en ese canal entre sí. Esto le da un total de seis DIPUTADOs para elegir entre:

  • Datagrama

  • Solicitud-respuesta

  • Dúplex

  • Datagrama con sesiones

  • Solicitud-respuesta con sesiones

  • Dúplex con sesiones

Nota:

En el caso del transporte de UDP, el único MEP que se admite es el datagrama, ya que UDP es en sí mismo un protocolo de tipo desencadenar y omitir.

Sesiones y canales con sesiones

En el mundo de las redes, hay protocolos orientados a la conexión (por ejemplo, TCP) y protocolos sin conexión (por ejemplo, UDP). WCF usa el término sesión para significar una abstracción lógica similar a una conexión. Los protocolos WCF con sesión son similares a los protocolos de red orientados a la conexión y los protocolos WCF sin sesión son similares a los protocolos de red sin conexión.

En el modelo de objetos de canal, cada sesión lógica se manifiesta como una instancia de un canal con sesión. Por lo tanto, cada nueva sesión creada por el cliente y aceptada en el servicio corresponde a un nuevo canal con sesión en cada lado. En el diagrama siguiente se muestra, en la parte superior, la estructura de canales sin sesión y, en la parte inferior, la estructura de los canales con sesión.

Diagrama de flujo que muestra la estructura de canales sin sesión y con sesión

Un cliente crea un nuevo canal con sesión y envía un mensaje. En el lado del servicio, el agente de escucha del canal recibe este mensaje y detecta que pertenece a una nueva sesión, por lo que crea un nuevo canal con sesión y lo entrega a la aplicación (en respuesta a la aplicación que llama a AcceptChannel en el agente de escucha del canal). La aplicación recibe a continuación este mensaje y todos los mensajes subsiguientes enviados en la misma sesión a través del mismo canal con sesión.

Otro cliente (o el mismo cliente) crea una sesión nueva y envía un mensaje. El agente de escucha del canal detecta que este mensaje está en una nueva sesión y crea un nuevo canal con sesión. El proceso se repite.

Sin sesiones, no hay ninguna correlación entre canales y sesiones. Por consiguiente, un agente de escucha del canal crea solo un canal a través del cual se entregarán los mensajes recibidos a la aplicación. Tampoco hay ninguna ordenación de mensajes porque no hay ninguna sesión en la que mantener el orden de los mensajes. La parte superior del gráfico anterior muestra un intercambio de mensajes sin sesión.

Sesiones de inicio y finalización

Las sesiones se inician en el cliente mediante la creación de un nuevo canal con sesión. Se inician cuando el servicio recibe un mensaje enviado en una nueva sesión. Del mismo modo, las sesiones se finalizan cerrando o anulando un canal con sesión.

La excepción a esto es IDuplexSessionChannel, que se utiliza para enviar y recibir mensajes en un patrón de comunicación dúplex con estado de sesión. Es posible que un lado quiera dejar de enviar mensajes pero seguir recibiendo mensajes, por lo tanto, cuando se usa IDuplexSessionChannel un mecanismo que le permite cerrar la sesión de salida que indica que no enviará más mensajes, pero mantener abierta la sesión de entrada, lo que le permite seguir recibiendo mensajes.

En general, las sesiones se cierran en el lado saliente y no en el lado entrante. Es decir, los canales de salida con sesión pueden cerrarse, cerrando con ello la sesión. Cerrar un canal de salida con sesión hace que el correspondiente canal de entrada con sesión devuelva null a la aplicación que llama a IInputChannel.Receive en el IDuplexSessionChannel.

Sin embargo, los canales de entrada con sesión no deberían estar cerrados a menos que IInputChannel.Receive en IDuplexSessionChannel devuelva el valor null, indicando que la sesión ya está cerrada. Si IInputChannel.Receive en el IDuplexSessionChannel no ha devuelto null, cerrar un canal de entrada con sesión puede producir una excepción porque puede recibir mensajes inesperados al cerrarse. Si un receptor desea finalizar una sesión antes de que el remitente lo haga, debe llamar Abort a en el canal de entrada, que finaliza abruptamente la sesión.

Creación de canales con sesión

Como autor del canal con sesión, hay algunas cosas que el canal deberá hacer para proporcionar sesiones. En el lado del envío, el canal tendrá que:

  • Para cada canal nuevo, cree una nueva sesión y asóciela a un nuevo identificador de sesión, que es una cadena única. U obtener una nueva sesión a partir del canal con sesión debajo de usted en la pila.

  • Para cada mensaje enviado mediante este canal, si el canal creó la sesión (en lugar de obtenerla de la capa inferior a usted), debe asociar el mensaje con la sesión. En el caso de los canales de protocolo, normalmente esto se hace agregando un encabezado SOAP. En el caso de los canales de transporte, esto suele hacerse mediante la creación de una nueva conexión de transporte o la adición de información de sesión al protocolo de marco.

  • Para cada mensaje enviado mediante este canal, debe proporcionar las garantías de entrega mencionadas anteriormente. Si está confiando en el canal situado debajo de usted para proporcionar la sesión, ese canal también proporcionará las garantías de la entrega. Si proporciona la sesión usted mismo, debe implementar esas garantías como parte del protocolo. En general, si está escribiendo un canal de protocolo que asume WCF en ambos lados, puede requerir el transporte TCP o el canal de mensajes fiables y confiar en cualquiera de ellos para proporcionar una sesión.

  • Cuando se llame a ICommunicationObject.Close en tu canal, lleva a cabo el trabajo necesario para cerrar la sesión usando el tiempo de espera especificado o el predeterminado. Esto puede ser tan simple como llamar a Close en el canal debajo de usted (si acabara de obtener una sesión de él) o enviar un mensaje SOAP especial o cerrar una conexión de transporte.

  • Cuando se llama a Abort en su canal, finalice la sesión bruscamente sin realizar E/S. Esto puede significar no hacer nada o puede implicar la anulación de una conexión de red o algún otro recurso.

En el lado de recepción, el canal tendrá que:

  • Para cada mensaje entrante, el agente de escucha del canal debe detectar la sesión a la que pertenece. Si éste es el primer mensaje en la sesión, el agente de escucha del canal debe crear un nuevo canal y devolverlo desde la llamada a IChannelListener<TChannel>.AcceptChannel. De lo contrario, el agente de escucha del canal debe buscar el canal existente que corresponde a la sesión y entregar el mensaje a través de ese canal.

  • Si tu canal proporciona la sesión (junto con las garantías de entrega necesarias), puede que se requiera al lado de recepción realizar algunas acciones, como reordenar mensajes o enviar confirmaciones.

  • Cuando se llama a Close en su canal, realice el trabajo necesario para cerrar la sesión mediante el tiempo de espera especificado o el valor predeterminado. Esto podría dar lugar a excepciones si el canal recibe un mensaje mientras espera a que expire el tiempo de espera de cierre. Esto se debe a que el canal estará en estado de cierre cuando reciba un mensaje por lo que se producirá una.

  • Cuando se llama a Abort en su canal, finalice la sesión bruscamente sin realizar E/S. De nuevo, esto puede significar no hacer nada o puede implicar la anulación de una conexión de red o algún otro recurso.

Consulte también