Introducción al enrutamiento
El servicio de enrutamiento proporciona un intermediario de SOAP conectable genérico que es capaz de enrutar mensajes en función de su contenido. Con el servicio de enrutamiento, puede crear una lógica de enrutamiento compleja que le permita implementar escenarios como la agregación de servicios, el control de versiones del servicio, el enrutamiento de prioridad y el enrutamiento de multidifusión. El servicio de enrutamiento también proporciona un control de errores, que le permite preparar listas de extremos de reserva a los que se envían los mensajes si se produce un error al realizar un envío al extremo de destino principal.
Este tema está dirigido a aquellos usuarios que se están iniciando en el servicio de enrutamiento, y cubre la configuración básica y el hospedaje del servicio de enrutamiento.
Configuración
El servicio de enrutamiento se implementa como un servicio de WCF que expone uno o varios extremos de servicio. Estos extremos reciben mensajes de aplicaciones cliente y los enrutan a uno o más extremos de destino. El servicio proporciona RoutingBehavior, que se aplica a los extremos de servicio que expone el servicio. Este comportamiento se utiliza para configurar varios aspectos del funcionamiento del servicio. Para facilitar la configuración al utilizar un archivo de configuración, los parámetros se especifican en RoutingBehavior. En escenarios basados en código, estos parámetros se especificarían como parte de un objeto RoutingConfiguration, que se puede pasar a continuación a RoutingBehavior.
Al iniciarse, este comportamiento agrega el objeto SoapProcessingBehavior, que se utiliza para realizar el procesamiento de SOAP de mensajes, a los extremos de cliente. Esto permite al servicio de enrutamiento transmitir mensajes a los extremos que requieren un MessageVersion diferente al del extremo mediante el que se recibió el mensaje. RoutingBehavior también registra una extensión de servicio, RoutingExtension, que proporciona un punto de accesibilidad para modificar la configuración del servicio de enrutamiento en tiempo de ejecución.
La clase RoutingConfiguration proporciona un medio coherente para configurar y actualizar la configuración del servicio de enrutamiento. Contiene parámetros que actúan como configuración del servicio de enrutamiento, y sirve para configurar RoutingBehavior cuando se inicia el servicio o se pasa a RoutingExtension para modificar la configuración de enrutamiento en tiempo de ejecución.
La lógica de enrutamiento utilizada para realizar el enrutamiento basado en el contenido de mensajes se define agrupando varios objetos MessageFilter en tablas de filtro (objetosMessageFilterTable). Los mensajes entrantes se evalúan en comparación con los filtros de mensaje contenidos en la tabla de filtros y se reenvían a un extremo de destino cuando un valor MessageFilter coincide con el mensaje. La tabla de filtros que se debería utilizar para enrutar los mensajes se especifica mediante el objeto RoutingBehavior de la configuración o a través de código, utilizando el objeto RoutingConfiguration.
Definición de extremos
Pese a que pueda parecer que debería iniciar su configuración definiendo la lógica de enrutamiento que va a utilizar, el primer paso sería realmente determinar la forma de los extremos a los que va a enrutar mensajes. El servicio de enrutamiento utiliza contratos que definen la forma de los canales utilizados para recibir y enviar mensajes y, por consiguiente, la forma del canal de entrada debe coincidir con la del canal de salida. Por ejemplo, si va a enrutar mensajes a extremos que utilizan la forma de canal "solicitud-respuesta", entonces debe utilizar un contrato compatible en los extremos entrantes, como IRequestReplyRouter.
Esto significa que, si sus extremos de destino utilizan contratos con varios patrones de comunicación (como la combinación de operaciones unidireccionales y bidireccionales), no puede crear ningún extremo de servicio único que pueda recibir y enrutar mensajes a todos ellos. Debe determinar qué extremos tienen formas compatibles y definir uno o varios extremos de servicio para recibir los mensajes que se van a enrutar a los extremos de destino.
Nota: |
---|
Al trabajar con contratos que especifican varios patrones de comunicación (como una combinación de operaciones unidireccionales y bidireccionales), una solución alternativa sería usar un contrato dúplex en el servicio de enrutamiento, como IDuplexSessionRouter. Sin embargo, esto implica que el enlace debe ser capaz de realizar una comunicación dúplex, algo que puede no ser posible en todos los escenarios. En escenarios en los que esto no sea posible, puede ser necesario dividir la comunicación en varios extremos o modificar la aplicación. |
Para obtener más información sobre los contratos de enrutamiento, vea Enrutar contratos.
Una vez definido el extremo de servicio, puede utilizar RoutingBehavior para asociar un objeto RoutingConfiguration concreto al extremo. Al configurar el servicio de enrutamiento utilizando un archivo de configuración, RoutingBehavior se utiliza para especificar la tabla de filtros que contiene la lógica de enrutamiento utilizada para procesar los mensajes recibidos en este extremo. Si va a configurar el servicio de enrutamiento mediante programación, puede especificar la tabla de filtros utilizando el objeto RoutingConfiguration.
En el siguiente ejemplo, se definen los extremos de cliente y servicio que usa el servicio de enrutamiento tanto mediante programación como por medio de un archivo de configuración.
<services>
<!--ROUTING SERVICE -->
<service behaviorConfiguration="routingData"
name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8000/routingservice/router"/>
</baseAddresses>
</host>
<!-- Define the service endpoints that are receive messages -->
<endpoint address=""
binding="wsHttpBinding"
name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IRequestReplyRouter" /> </service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="routingData">
<serviceMetadata httpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routing filterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<!-- Define the client endpoint(s) to route messages to -->
<endpoint name="CalculatorService"
address="https://localhost:8000/servicemodelsamples/service"
binding="wsHttpBinding" contract="*" />
</client>
//set up some communication defaults
string clientAddress = "https://localhost:8000/servicemodelsamples/service";
string routerAddress = "https://localhost:8000/routingservice/router";
Binding routerBinding = new WSHttpBinding();
Binding clientBinding = new WSHttpBinding();
//add the endpoint the router uses to receive messages
serviceHost.AddServiceEndpoint(
typeof(IRequestReplyRouter),
routerBinding,
routerAddress);
//create the client endpoint the router routes messages to
ContractDescription contract = ContractDescription.GetContract(
typeof(IRequestReplyRouter));
ServiceEndpoint client = new ServiceEndpoint(
contract,
clientBinding,
new EndpointAddress(clientAddress));
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
….
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(
new RoutingBehavior(rc));
En este ejemplo, se configura el servicio de enrutamiento para que exponga un extremo único con una dirección "https://localhost:8000/routingservice/router", que se utiliza para recibir los mensajes que se van a enrutar. Dado que los mensajes se enrutan a extremos solicitud-respuesta, el extremo de servicio utiliza el contrato IRequestReplyRouter. Esta configuración también define un extremo de cliente único de "https://localhost:8000/servicemodelsample/service" al que se enrutan los mensajes. La tabla de filtros denominada "routingTable1" (que no se muestra) contiene la lógica de enrutamiento que se utiliza para enrutar los mensajes y está asociada al extremo de servicio mediante RoutingBehavior (para un archivo de configuración) o RoutingConfiguration (para la configuración mediante programación).
Lógica de enrutamiento
Para definir la lógica de enrutamiento utilizada para enrutar los mensajes, debe determinar sobre qué datos se puede actuar de entre los contenidos dentro de los mensajes entrantes. Por ejemplo, si todos los extremos de destino a los que va a enrutar mensajes comparten las mismas acciones SOAP, el valor de la acción SOAP incluida dentro del mensaje no es un buen indicador de a qué extremo concreto se debe enrutar el mensaje. Si debe enrutar los mensajes únicamente a un extremo concreto, debe filtrar según los datos que identifiquen exclusivamente el extremo de destino al que se enruta el mensaje.
El servicio de enrutamiento proporciona varias implementaciones de MessageFilter que inspeccionan valores específicos del mensaje, como la dirección, la acción, el nombre del extremo o incluso una consulta XPath. Si ninguna de estas implementaciones satisface sus necesidades, puede crear una implementación de MessageFilter personalizada. Para obtener más información sobre los filtros de mensaje y una comparación de las implementaciones que utiliza el servicio de enrutamiento, vea Filtros de mensajes y Elegir un filtro.
Los distintos filtros de mensajes se organizan en tablas de filtros que asocian cada valor de MessageFilter con un extremo de destino. Opcionalmente, la tabla de filtros también se puede utilizar para especificar una lista de extremos de reserva a los que el servicio de enrutamiento intentará enviar el mensaje en caso de que se produzca un error de transmisión.
De forma predeterminada, todos los filtros de mensajes de una tabla de filtros se evalúan simultáneamente; sin embargo, puede especificar Priority para que la evaluación de los filtros se efectúe en un orden concreto. Primero se evalúan todas las entradas de mayor prioridad y los filtros de mensaje de menor prioridad no se evalúan si se detecta una coincidencia en un nivel de prioridad más alto. Para obtener más información sobre las tablas de filtros, vea Filtros de mensajes.
En los siguientes ejemplos, se utiliza MatchAllMessageFilter, que evalúa todos los mensajes como true. Este valor de MessageFilter se agrega a la tabla de filtros "routingTable1", que asocia MessageFilter al extremo de cliente denominado "CalculatorService". A continuación, RoutingBehavior especifica que esta tabla se debe utilizar para enrutar los mensajes procesados por el extremo de servicio.
<behaviors>
<serviceBehaviors>
<behavior name="routingData">
<serviceMetadata httpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routing filterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="MatchAllFilter1" endpointName="CalculatorService" />
</filters>
</table>
</filterTables>
</routing>
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
//create the endpoint list that contains the endpoints to route to
//in this case we have only one
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
//add a MatchAll filter to the Router's filter table
//map it to the endpoint list defined earlier
//when a message matches this filter, it is sent to the endpoint contained in the list
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
Nota: |
---|
De forma predeterminada, el servicio de enrutamiento solo evalúa los encabezados del mensaje. Para permitir a los filtros tener acceso al cuerpo del mensaje, debe establecer RouteOnHeadersOnly en false. |
Multidifusión
Aunque muchas configuraciones del servicio de enrutamiento utilizan una lógica de filtros exclusiva que enruta los mensajes solo a un extremo específico, puede que tenga que enrutar un mensaje determinado a varios extremos de destino. Para difundir un mensaje a varios destinos, deben cumplirse las siguientes condiciones:
La forma del canal no puede ser de "solicitud-respuesta" (aunque sí unidireccional o dúplex), porque la aplicación cliente solo puede recibir una respuesta para cada solicitud.
Varios filtros deben devolver true al evaluar el mensaje.
Si se cumplen estas condiciones, el mensaje se enruta a todos los extremos de todos los filtros que se evalúan como true. En el siguiente ejemplo, se define una configuración de enrutamiento que enruta mensajes a los dos extremos si la dirección del extremo del mensaje es https://localhost:8000/routingservice/router/rounding.
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
<filter name="RoundingFilter1" filterType="EndpointAddress"
filterData="https://localhost:8000/routingservice/router/rounding" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="MatchAllFilter1" endpointName="CalculatorService" />
<add filterName="RoundingFilter1" endpointName="RoundingCalcService" />
</filters>
</table>
</filterTables>
</routing>
rc.FilterTable.Add(new MatchAllMessageFilter(), calculatorEndpointList);
rc.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress(
"https://localhost:8000/routingservice/router/rounding")),
roundingCalcEndpointList);
Procesamiento de SOAP
Para admitir el enrutamiento de mensajes entre protocolos distintos, RoutingBehavior agrega de forma predeterminada SoapProcessingBehavior a todos los extremos de cliente a los que se enrutan los mensajes. Este comportamiento crea automáticamente un nuevo valor MessageVersion antes de enrutar el mensaje al extremo, al tiempo que crea otro MessageVersion compatible para cualquier documento de respuesta antes de devolverlo a la aplicación cliente que efectúa la solicitud.
Los pasos que se siguen para crear un nuevo MessageVersion para el mensaje de salida son los siguientes:
Procesamiento de solicitudes
Obtenga MessageVersion del enlace o canal de salida.
Obtenga el lector del cuerpo del mensaje original.
Cree un nuevo mensaje con la misma acción y el mismo lector de cuerpo, y un nuevo valor MessageVersion.
Si Addressing ! = Addressing.None, copie los encabezados To, From, FaultTo y RelatesTo en el nuevo mensaje.
Copie todas las propiedades del mensaje en el nuevo mensaje.
Almacene el mensaje de solicitud original para utilizarlo al procesar la respuesta.
Devuelva el nuevo mensaje de solicitud.
Procesamiento de respuestas
Obtenga el valor MessageVersion del mensaje de solicitud original.
Obtenga el lector del cuerpo del mensaje de respuesta recibido.
Cree un nuevo mensaje de respuesta con la misma acción y lector del cuerpo, y utilice MessageVersion del mensaje de solicitud original.
Si Addressing ! = Addressing.None, copie los encabezados To, From, FaultTo y RelatesTo en el nuevo mensaje.
Copie las propiedades del mensaje en el nuevo mensaje.
Devuelva el nuevo mensaje de respuesta.
De forma predeterminada, SoapProcessingBehavior se agrega automáticamente a los extremos de cliente por medio de RoutingBehavior cuando se inicia el servicio; sin embargo, puede controlar si el procesamiento de SOAP se agrega a todos los extremos de cliente mediante la propiedad SoapProcessingEnabled. También puede agregar el comportamiento directamente a un extremo específico, y habilitar o deshabilitar este comportamiento en los extremos si se requiere un control de procesamiento de SOAP más granular.
Nota: |
---|
Si el procesamiento de SOAP está deshabilitado para un extremo que requiere un valor MessageVersion diferente al del mensaje de solicitud original, debe proporcionar un mecanismo personalizado para que realice todas las modificaciones de SOAP que sean necesarias antes de enviar el mensaje al extremo de destino. |
En los siguientes ejemplos, la propiedad soapProcessingEnabled se utiliza para evitar que SoapProcessingBehavior se agregue automáticamente a todos los extremos de cliente.
<behaviors>
<!--default routing service behavior definition-->
<serviceBehaviors>
<behavior name="routingConfiguration">
<routing filterTableName="filterTable1" soapProcessingEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
//create the default RoutingConfiguration
RoutingConfiguration rc = new RoutingConfiguration();
rc.SoapProcessingEnabled = false;
Configuración dinámica
Al agregar extremos de cliente adicionales, o bien cuando necesite modificar los filtros que se utilizan para enrutar los mensajes, debe encontrar una forma de actualizar dinámicamente la configuración en tiempo de ejecución para evitar la interrupción del servicio en los extremos que estén recibiendo mensajes a través del servicio de enrutamiento en ese momento. Modificar un archivo de configuración o el código de la aplicación host no siempre es suficiente, porque todos los métodos necesitan que se recicle la aplicación y esto conduciría a la pérdida potencial de todos los mensajes que estuvieran en tránsito en ese momento, así como a un posible tiempo de inactividad mientras se aguarda al reinicio del servicio.
El objeto RoutingConfiguration solo puede modificarse mediante programación. Aunque puede configurar el servicio inicialmente utilizando un archivo de configuración, solo puede modificar la configuración en tiempo de ejecución construyendo un nuevo RoutingConfigution y pasándolo como parámetro al método ApplyConfiguration expuesto por la extensión de servicio RoutingExtension. Todos los mensajes que estén en tránsito siguen enrutándose con la configuración anterior, mientras que los mensajes que se reciban después de la llamada a ApplyConfiguration utilizarán la nueva configuración. En el siguiente ejemplo, se muestra cómo crear una instancia del servicio de enrutamiento y cómo modificar después la configuración.
RoutingConfiguration routingConfig = new RoutingConfiguration();
routingConfig.RouteOnHeadersOnly = true;
routingConfig.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
RoutingBehavior routing = new RoutingBehavior(routingConfig);
routerHost.Description.Behaviors.Add(routing);
routerHost.Open();
// Construct a new RoutingConfiguration
RoutingConfiguration rc2 = new RoutingConfiguration();
ServiceEndpoint clientEndpoint = new ServiceEndpoint();
ServiceEndpoint clientEndpoint2 = new ServiceEndpoint();
// Add filters to the FilterTable in the new configuration
rc2.FilterTable.add(new MatchAllMessageFilter(),
new List<ServiceEndpoint>() { clientEndpoint });
rc2.FilterTable.add(new MatchAllMessageFilter(),
new List<ServiceEndpoint>() { clientEndpoint2 });
rc2.RouteOnHeadersOnly = false;
// Apply the new configuration to the Routing Service hosted in
routerHost.routerHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc2);
Nota: |
---|
Al actualizar el servicio de enrutamiento de esta manera, solo es posible pasar una nueva configuración. No se puede modificar únicamente elementos determinados de la configuración actual o anexar nuevas entradas a la configuración actual. Debe crear y pasar una nueva configuración que reemplace la existente. |
Nota: |
---|
Todas las sesiones que se abrieron con la configuración anterior seguirán utilizándola. Sólo las nuevas sesiones usarán la configuración nueva. |
Control de errores
Si se encuentra algún valor CommunicationException al intentar enviar un mensaje, tiene lugar el control de errores. Estas excepciones indican normalmente que se encontró un problema al intentar establecer comunicación con el extremo de cliente definido, como EndpointNotFoundException, ServerTooBusyException o CommunicationObjectFaultedException. El código de control de errores también lo detectará e intentará volver a realizar el envío cuando se produzca una TimeoutException, otro tipo habitual de excepción que no se deriva de CommunicationException.
Cuando se produce una de las excepciones anteriores, el servicio de enrutamiento no puede establecer comunicación con una lista de extremos de reserva. Si se produce un error de comunicación en todos los extremos de reserva, o bien si un extremo devuelve una excepción que indica un error dentro del servicio de destino, el servicio de enrutamiento devuelve un error a la aplicación cliente.
Nota: |
---|
La funcionalidad del control de errores captura y administra excepciones que se producen al intentar enviar un mensaje y al intentar cerrar un canal. El código de control de errores no está diseñado para detectar o administrar excepciones creadas por los extremos de la aplicación con los que se comunica, sino que una FaultException lanzada por un servicio aparece en el servicio de enrutamiento como FaultMessage y se devuelve al cliente. |
Traza de excepciones
Cuando no se puede enviar un mensaje a un extremo de una lista, el servicio de enrutamiento realiza una traza de los datos de excepción resultantes y adjunta los detalles de la excepción como una propiedad del mensaje denominada Exceptions. Esto conserva los datos de la excepción y permite al usuario tener acceso mediante programación a través de un inspector del mensaje. Los datos de la excepción se almacenan por mensaje en un diccionario que asigna el nombre del extremo a los detalles de la excepción producidos al intentar enviarle un mensaje.
Extremos de reserva
Las entradas de la tabla de filtros pueden especificar también una lista de extremos de reserva que se utilizarán cuando se produzcan errores de transmisión al enviar mensajes al extremo principal. Si se produce este tipo de error, el servicio de enrutamiento intenta transmitir el mensaje a la primera entrada de la lista de extremos de reserva. Si este intento resulta fallido también, se prueba con el extremo de reserva siguiente de la lista. El servicio de enrutamiento sigue enviando el mensaje a cada uno de los extremos de la lista hasta que el mensaje se recibe correctamente, todos los extremos devuelven un error de transmisión o se produce un error distinto en el extremo.
En los siguientes ejemplos, se configura el servicio de enrutamiento para que utilice una lista de reserva.
<routing>
<filters>
<!-- Create a MatchAll filter that catches all messages -->
<filter name="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<!-- Set up the Routing Service's Message Filter Table -->
<filterTable name="filterTable1">
<!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
<!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
<!-- Listed in the backupEndpointList -->
<add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<!-- Create the backup endpoint list -->
<backupLists>
<!-- Add an endpoint list that contains the backup destinations -->
<backupList name="backupEndpointList">
<add endpointName="realDestination" />
<add endpointName="backupDestination" />
</backupList>
</backupLists>
</routing>
//create the endpoint list that contains the service endpoints we want to route to
List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();
//add the endpoints in the order that the Routing Service should contact them
//first add the endpoint that we know is down
//clearly, normally you wouldn't know that this endpoint was down by default
backupList.Add(fakeDestination);
//then add the real Destination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationException when sending
//to the previous endpoint in the list.
backupList.Add(realDestination);
//add the backupDestination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationsException when sending
//to the previous endpoints in the list
backupList.Add(backupDestination);
//create the default RoutingConfiguration option
RoutingConfiguration rc = new RoutingConfiguration();
//add a MatchAll filter to the Routing Configuration's filter table
//map it to the list of endpoints defined above
//when a message matches this filter, it is sent to the endpoints in the list in order
//if an endpoint is down or doesn't respond (which the first endpoint won't
//since the client doesn't exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);
Patrones de error admitidos
En la siguiente tabla, se describen los patrones que son compatibles con el uso de listas de extremos de reserva, junto con notas en las que se describen los detalles del control de errores de patrones específicos.
Patrón | Sesión | Transacción | Contexto de recepción | Lista de reserva admitida | Notas |
---|---|---|---|---|---|
Unidireccional |
Sí |
Intenta reenviar el mensaje a un extremo de reserva. Si este mensaje se envía por multidifusión, solo el mensaje del canal fallido se mueve a su destino de reserva. |
|||
Unidireccional |
No |
Se lanza una excepción y se deshace la transacción. |
|||
Unidireccional |
Sí |
Intenta reenviar el mensaje a un extremo de reserva. Una vez recibido correctamente el mensaje, rellene todos los contextos de recepción. Si ninguno de los extremos recibe correctamente el mensaje, no rellene el contexto de recepción. Cuando este mensaje se envía por multidifusión, el contexto de recepción solo se rellena si al menos un extremo (principal o de reserva) recibe correctamente el mensaje. Si ninguno de los extremos de las rutas de acceso de multidifusión recibe el mensaje correctamente, no rellene el contexto de recepción. |
|||
Unidireccional |
Sí |
Anule la transacción anterior, cree una transacción nueva y reenvíe todos los mensajes. Los mensajes que detectaron un error se transmiten a un destino de copia de seguridad. Una vez creada una transacción que realiza correctamente todas las transmisiones, rellene los contextos de recepción y confirme la transacción. |
|||
Unidireccional |
Sí |
Intenta reenviar el mensaje a un extremo de reserva. En un escenario de multidifusión solo se reenvían a destinos de reserva los mensajes de sesiones en las que se produjo un error o que no pudieron cerrarse. |
|||
Unidireccional |
No |
Se lanza una excepción y se deshace la transacción. |
|||
Unidireccional |
Sí |
Intenta reenviar el mensaje a un extremo de reserva. Una vez que todos los envíos de mensaje se realizan correctamente, la sesión indica que no hay más mensajes y el servicio de enrutamiento cierra todos los canales de sesión salientes, se rellenan todos los contextos de recepción y se cierra el canal de sesión entrante. |
|||
Unidireccional |
Sí |
Anule la transacción actual y cree una nueva. Reenvíe todos los mensajes anteriores de la sesión. Una vez que se crea una transacción en la que todos los mensajes se envían correctamente y la sesión indica que no hay más mensajes, se cierran todos los canales de sesión salientes, se rellenan todos los contextos de recepción con la transacción, se cierra el canal de sesión entrante y se confirma la transacción. Cuando las sesiones son de multidifusión, los mensajes que no produjeron errores se reenvían al mismo destino y los mensajes que sí los produjeron se envían a los destinos de reserva. |
|||
Bidireccional |
Sí |
Realice un envío a un destino de reserva. Una vez que el canal devuelve un mensaje de respuesta, devuelva la respuesta al cliente original. |
|||
Bidireccional |
Sí |
Envíe todos los mensajes del canal a un destino de reserva. Una vez que el canal devuelve un mensaje de respuesta, devuelva la respuesta al cliente original. |
|||
Bidireccional |
No |
Se lanza una excepción y se deshace la transacción. |
|||
Bidireccional |
No |
Se lanza una excepción y se deshace la transacción. |
|||
Dúplex |
No |
Actualmente, no se admite una comunicación dúplex que no sea de sesiones. |
|||
Dúplex |
Sí |
Realice un envío a un destino de reserva. |
Hospedaje
Dado que el servicio de enrutamiento se implementa como un servicio WCF, debe auto-hospedarse en una aplicación o ser hospedado por un servidor IIS o WAS. Se recomienda que el servicio de enrutamiento se hospede bien en un IIS, en un WAS o en una aplicación de un servicio Windows para que pueda aprovecharse de las características de administración de ciclo de vida y de inicio automático que están disponibles en estos entornos de hospedaje.
En el siguiente ejemplo, se muestra cómo hospedar el servicio de enrutamiento en una aplicación.
using (ServiceHost serviceHost =
new ServiceHost(typeof(RoutingService)))
Para hospedar el servicio de enrutamiento dentro de un IIS o WAS, debe crear un archivo de servicio (.svc) o utilizar la activación basada en configuración del servicio. Al utilizar un archivo de servicio, debe especificar la clase RoutingService que utiliza el parámetro del servicio. El siguiente ejemplo contiene un archivo de servicio de ejemplo que se puede utilizar para hospedar el servicio de enrutamiento con IIS o WAS.
<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" %>