Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il servizio di routing fornisce un intermediario SOAP collegabile generico in grado di instradare i messaggi in base al contenuto del messaggio. Con il servizio di routing è possibile creare una logica di routing complessa che consente di implementare scenari come l'aggregazione dei servizi, il controllo delle versioni del servizio, il routing prioritario e il routing multicast. Il servizio di routing fornisce anche la gestione degli errori che consente di configurare elenchi di endpoint di backup, a cui vengono inviati messaggi se si verifica un errore durante l'invio all'endpoint di destinazione primario.
Questo argomento è destinato a coloro che non hanno familiarità con il servizio di routing e illustra la configurazione di base e l'hosting del servizio di routing.
Configurazione
Il servizio di routing viene implementato come servizio WCF che espone uno o più endpoint di servizio che ricevono messaggi dalle applicazioni client e instradano i messaggi a uno o più endpoint di destinazione. Il servizio fornisce un RoutingBehavior, che viene applicato agli endpoint esposti dal servizio. Questo comportamento viene usato per configurare vari aspetti del funzionamento del servizio. Per semplificare la configurazione quando si usa un file di configurazione, i parametri vengono specificati in RoutingBehavior. Negli scenari basati su codice, questi parametri vengono specificati come parte di un RoutingConfiguration oggetto , che può quindi essere passato a un RoutingBehavior.
All'avvio, questo comportamento aggiunge il SoapProcessingBehavior, che viene utilizzato per eseguire l'elaborazione SOAP dei messaggi, agli endpoint del client. In questo modo il servizio di routing può trasmettere messaggi agli endpoint che richiedono un MessageVersion diverso rispetto all'endpoint in cui è stato ricevuto il messaggio. RoutingBehavior registra anche un'estensione del RoutingExtensionservizio, , che fornisce un punto di accessibilità per la modifica della configurazione del servizio di routing in fase di esecuzione.
La classe RoutingConfiguration offre un mezzo coerente per configurare e aggiornare la configurazione del servizio di routing. Contiene parametri che fungono da impostazioni per il servizio di routing e vengono usati per configurare RoutingBehavior all'avvio del servizio o che vengono passati a RoutingExtension per modificare la configurazione del routing in fase di esecuzione.
La logica di routing usata per eseguire il routing basato sul contenuto dei messaggi viene definita raggruppando più MessageFilter oggetti in tabelle di filtro (MessageFilterTable<TFilterData> oggetti). I messaggi in arrivo vengono valutati rispetto ai filtri messaggi contenuti nella tabella di filtro e per ogni MessageFilter che corrisponde al messaggio, viene inoltrato a un endpoint di destinazione. La tabella di filtro che deve essere usata per instradare i messaggi viene specificata tramite RoutingBehavior nella configurazione o tramite il codice usando l'oggetto RoutingConfiguration .
Definizione degli endpoint
Anche se potrebbe sembrare che sia necessario avviare la configurazione definendo la logica di routing che verrà usata, il primo passaggio dovrebbe effettivamente essere quello di determinare la forma degli endpoint a cui verranno instradati i messaggi. Il servizio di routing utilizza contratti che definiscono la forma dei canali utilizzati per ricevere e inviare messaggi, pertanto la forma del canale di input deve corrispondere a quella del canale di output. Ad esempio, se si esegue il routing agli endpoint che usano la forma del canale request-reply, è necessario usare un contratto compatibile negli endpoint in ingresso, ad esempio IRequestReplyRouter.
Ciò significa che se gli endpoint di destinazione usano contratti con più modelli di comunicazione ,ad esempio la combinazione di operazioni unidirezionali e bidirezionali, non è possibile creare un singolo endpoint di servizio in grado di ricevere e instradare i messaggi a tutti. È necessario determinare quali endpoint hanno forme compatibili e definire uno o più endpoint di servizio che verranno usati per ricevere messaggi da instradare agli endpoint di destinazione.
Annotazioni
Quando si usano contratti che specificano più modelli di comunicazione ,ad esempio una combinazione di operazioni unidirezionali e bidirezionali, una soluzione alternativa consiste nell'usare un contratto duplex nel servizio di routing, ad esempio IDuplexSessionRouter. Ciò significa tuttavia che l'associazione deve essere in grado di comunicare in modo bidirezionale, il che potrebbe non essere possibile in tutti gli scenari. Negli scenari in cui ciò non è possibile, potrebbe essere necessario considerare la comunicazione in più endpoint o modificare l'applicazione.
Per altre informazioni sui contratti di routing, vedere Contratti di routing.
Dopo aver definito l'endpoint del servizio, è possibile usare RoutingBehavior per associare un routingConfiguration specifico all'endpoint. Quando si configura il servizio di routing usando un file di configurazione, il RoutingBehavior viene usato per specificare la tabella di filtro contenente la logica di routing usata per elaborare i messaggi ricevuti in questo endpoint. Se si configura il servizio di routing a livello di codice, è possibile specificare la tabella dei filtri usando RoutingConfiguration.
Nell'esempio seguente vengono definiti gli endpoint del servizio e client usati dal servizio di routing sia a livello di codice che tramite un file di configurazione.
<services>
<!--ROUTING SERVICE -->
<service behaviorConfiguration="routingData"
name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<add baseAddress="http://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="http://localhost:8000/servicemodelsamples/service"
binding="wsHttpBinding" contract="*" />
</client>
//set up some communication defaults
string clientAddress = "http://localhost:8000/servicemodelsamples/service";
string routerAddress = "http://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));
In questo esempio viene configurato il servizio di routing per esporre un singolo endpoint con un indirizzo di http://localhost:8000/routingservice/router
, che viene usato per ricevere messaggi da instradare. Poiché i messaggi vengono indirizzati agli endpoint request-reply, l'endpoint di servizio usa il IRequestReplyRouter contratto. Questa configurazione definisce anche un singolo endpoint client di http://localhost:8000/servicemodelsample/service
che i messaggi vengono indirizzati a. La tabella dei filtri (non visualizzata) denominata "routingTable1" contiene la logica di routing usata per instradare i messaggi ed è associata all'endpoint del servizio tramite RoutingBehavior (per un file di configurazione) o RoutingConfiguration (per la configurazione a livello di codice).
Logica di routing
Per definire la logica di routing usata per instradare i messaggi, è necessario determinare quali dati contenuti all'interno dei messaggi in arrivo possono essere eseguiti in modo univoco. Ad esempio, se tutti gli endpoint di destinazione verso cui si effettua il routing condividono le stesse azioni SOAP, il valore dell'azione presente nel messaggio non è un buon indicatore di quale endpoint specifico il messaggio debba essere instradato. Se è necessario instradare in modo univoco i messaggi a un endpoint specifico, è necessario filtrare in base ai dati che identificano in modo univoco l'endpoint di destinazione a cui viene instradato il messaggio.
Il servizio di routing fornisce diverse implementazioni di MessageFilter che controllano valori specifici all'interno del messaggio, ad esempio l'indirizzo, l'azione, il nome dell'endpoint o anche una query XPath. Se nessuna di queste implementazioni soddisfa le proprie esigenze, è possibile creare un'implementazione di MessageFilter personalizzata . Per altre informazioni sui filtri dei messaggi e un confronto delle implementazioni usate dal servizio di routing, vedere Filtri messaggi e Scelta di un filtro.
Più filtri di messaggi sono organizzati insieme in tabelle di filtro, che associano ogni MessageFilter a un endpoint di destinazione. Facoltativamente, la tabella dei filtri può essere usata anche per specificare un elenco di endpoint di backup a cui il servizio di routing tenterà di inviare il messaggio in caso di errore di trasmissione.
Per impostazione predefinita, tutti i filtri dei messaggi all'interno di una tabella di filtro vengono valutati contemporaneamente; È tuttavia possibile specificare un Priority oggetto che determina la valutazione dei filtri dei messaggi in un ordine specifico. Tutte le voci con priorità più alta vengono valutate per prime e i filtri dei messaggi delle priorità inferiori non vengono valutati se viene trovata una corrispondenza a un livello di priorità superiore. Per altre informazioni sulle tabelle di filtro, vedere Filtri messaggi.
Negli esempi seguenti viene usato MatchAllMessageFilter, che restituisce true
per tutti i messaggi.
Questo MessageFilter viene aggiunto alla tabella di filtro "routingTable1", che associa MessageFilter all'endpoint client denominato "CalculatorService".
RoutingBehavior specifica quindi che questa tabella deve essere usata per instradare i messaggi elaborati dall'endpoint del servizio.
<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);
Annotazioni
Per impostazione predefinita, il servizio di routing valuta solo le intestazioni del messaggio. Per consentire ai filtri di accedere al corpo del messaggio, è necessario impostare su RouteOnHeadersOnlyfalse
.
multicast
Sebbene molte configurazioni del servizio di routing usino una logica di filtro esclusiva che instrada i messaggi a un solo endpoint specifico, potrebbe essere necessario instradare un determinato messaggio a più endpoint di destinazione. Per eseguire il multicast di un messaggio a più destinazioni, è necessario che le condizioni seguenti siano vere:
La forma del canale non deve essere request-reply (anche se può essere unidirezionale o duplex), perché è possibile ricevere una sola risposta dall'applicazione client in risposta alla richiesta.
Più filtri devono restituire
true
quando si valuta il messaggio.
Se queste condizioni vengono soddisfatte, il messaggio viene indirizzato a tutti gli endpoint di tutti i filtri che restituiscono true
. Nell'esempio seguente viene definita una configurazione di routing che comporta l'instradamento dei messaggi a entrambi gli endpoint se l'indirizzo dell'endpoint nel messaggio è http://localhost:8000/routingservice/router/rounding
.
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
<filter name="RoundingFilter1" filterType="EndpointAddress"
filterData="http://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(
"http://localhost:8000/routingservice/router/rounding")),
roundingCalcEndpointList);
Elaborazione SOAP
Per supportare il routing dei messaggi tra protocolli diversi, RoutingBehavior aggiunge per impostazione predefinita a SoapProcessingBehavior tutti gli endpoint client a cui vengono indirizzati i messaggi. Questo comportamento crea automaticamente un nuovo MessageVersion prima di instradare il messaggio all'endpoint, oltre a creare un MessageVersion compatibile per qualsiasi documento di risposta prima di restituirlo all'applicazione client richiedente.
I passaggi eseguiti per creare un nuovo MessageVersion per il messaggio in uscita sono i seguenti:
Elaborazione delle richieste
Ottieni la MessageVersion dell'associazione/canale in uscita.
Ottenere il lettore del corpo per il messaggio originale.
Crea un nuovo messaggio con la stessa azione, il lettore del contenuto del messaggio e una nuova versione del messaggio MessageVersion.
Quando Addressing != Addressing.None, copia le intestazioni To, From, FaultTo e RelatesTo nel nuovo messaggio.
Copiare tutte le proprietà del messaggio nel nuovo messaggio.
Archiviare il messaggio di richiesta originale da usare durante l'elaborazione della risposta.
Restituisce il nuovo messaggio di richiesta.
Elaborazione della risposta
Ottenere MessageVersion del messaggio di richiesta originale.
Ottenere il lettore del corpo per il messaggio di risposta ricevuto.
Crea un nuovo messaggio di risposta con la stessa azione, il lettore del corpo del messaggio e la MessageVersion del messaggio di richiesta originale.
Quando Addressing != Addressing.None, copia le intestazioni To, From, FaultTo e RelatesTo nel nuovo messaggio.
Copiare le proprietà del messaggio nel nuovo messaggio.
Restituisce il nuovo messaggio di risposta.
Per impostazione predefinita, SoapProcessingBehavior viene aggiunto automaticamente agli endpoint client dal RoutingBehavior quando il servizio viene avviato; tuttavia, è possibile controllare se l'elaborazione SOAP viene aggiunta a tutti gli endpoint client utilizzando la proprietà SoapProcessingEnabled. È anche possibile aggiungere il comportamento direttamente a un endpoint specifico e abilitare o disabilitare questo comportamento a livello di endpoint se è necessario un controllo più granulare dell'elaborazione SOAP.
Annotazioni
Se l'elaborazione SOAP è disabilitata per un endpoint che richiede un MessageVersion diverso da quello del messaggio di richiesta originale, è necessario fornire un meccanismo personalizzato per eseguire eventuali modifiche SOAP necessarie prima di inviare il messaggio all'endpoint di destinazione.
Negli esempi seguenti viene usata la proprietà soapProcessingEnabled per impedire l'aggiunta automatica di SoapProcessingBehavior a tutti gli endpoint client.
<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;
Configurazione dinamica
Quando si aggiungono altri endpoint client o è necessario modificare i filtri usati per instradare i messaggi, è necessario disporre di un modo per aggiornare la configurazione in modo dinamico in fase di esecuzione per impedire l'interruzione del servizio agli endpoint che attualmente ricevono messaggi tramite il servizio di routing. La modifica di un file di configurazione o del codice dell'applicazione host non è sempre sufficiente, perché entrambi i metodi richiedono il riciclo dell'applicazione, il che comporta la potenziale perdita di eventuali messaggi attualmente in transito e il potenziale tempo di inattività durante l'attesa del riavvio del servizio.
È possibile modificare routingConfiguration solo a livello di codice. Anche se inizialmente è possibile configurare il servizio usando un file di configurazione, è possibile modificare la configurazione solo in fase di esecuzione creando una nuova RoutingConfiguration e passandola come parametro al ApplyConfiguration metodo esposto dall'estensione del RoutingExtension servizio. Tutti i messaggi attualmente in transito continuano a essere instradati usando la configurazione precedente, mentre i messaggi ricevuti dopo la chiamata a ApplyConfiguration usano la nuova configurazione. Nell'esempio seguente viene illustrata la creazione di un'istanza del servizio di routing e quindi la modifica della configurazione.
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);
Annotazioni
Quando si aggiorna il servizio di routing in questo modo, è possibile passare solo una nuova configurazione. Non è possibile modificare solo gli elementi selezionati della configurazione corrente o aggiungere nuove voci alla configurazione corrente; è necessario creare e passare una nuova configurazione che sostituisce quella esistente.
Annotazioni
Tutte le sessioni aperte usando la configurazione precedente continuano a usare la configurazione precedente. La nuova configurazione viene usata solo dalle nuove sessioni.
Gestione degli errori
CommunicationException Se si verifica un errore durante il tentativo di inviare un messaggio, viene eseguita la gestione degli errori. Queste eccezioni indicano in genere che si è verificato un problema durante il tentativo di comunicare con l'endpoint client definito, ad esempio EndpointNotFoundException, ServerTooBusyExceptiono CommunicationObjectFaultedException. Anche il codice di gestione degli errori intercetta e tenterà di riprovare a inviare quando si verifica un'eccezione TimeoutException , un'altra eccezione comune non derivata da CommunicationException.
Quando si verifica una delle eccezioni precedenti, il servizio di routing esegue il failover a un elenco di endpoint di backup. Se tutti gli endpoint di backup hanno esito negativo con un errore di comunicazione o se un endpoint restituisce un'eccezione che indica un errore all'interno del servizio di destinazione, il servizio di routing restituisce un errore all'applicazione client.
Annotazioni
La funzionalità di gestione degli errori acquisisce e gestisce le eccezioni che si verificano quando si tenta di inviare un messaggio e quando si tenta di chiudere un canale. Il codice di gestione degli errori non è progettato per rilevare o gestire le eccezioni create dagli endpoint dell'applicazione con cui comunica; un'eccezione FaultException generata da un servizio viene visualizzata nel servizio di routing come FaultMessage e viene restituita al client.
Se si verifica un errore quando un servizio di routing tenta di inoltrare un messaggio, potrebbe essere visualizzato un FaultException sul lato client, anziché un EndpointNotFoundException che riceveresti normalmente senza il servizio di routing. Un servizio di routing può quindi mascherare le eccezioni e non fornire trasparenza completa a meno che non si esaminino le eccezioni annidate.
Tracciamento delle eccezioni
Se l'invio di un messaggio a un endpoint in un elenco non riesce, il servizio di routing traccia i dati delle eccezioni risultanti e associa i dettagli dell'eccezione come proprietà del messaggio chiamata Exceptions. In questo modo vengono mantenuti i dati delle eccezioni e viene consentito l'accesso a livello di codice a un utente tramite un controllo messaggi. I dati dell'eccezione vengono archiviati per messaggio in un dizionario che esegue il mapping del nome dell'endpoint ai dettagli dell'eccezione rilevati durante il tentativo di inviare un messaggio.
Endpoint di backup
Ogni voce di filtro all'interno della tabella dei filtri può facoltativamente specificare un elenco di endpoint di backup, che vengono usati in caso di errore di trasmissione durante l'invio all'endpoint primario. Se si verifica un errore di questo tipo, il servizio di routing tenta di trasmettere il messaggio alla prima voce nell'elenco degli endpoint di backup. Se questo tentativo di invio rileva anche un errore di trasmissione, viene tentato l'endpoint successivo nell'elenco di backup. Il servizio di routing continua a inviare il messaggio a ogni endpoint dell'elenco finché il messaggio non viene ricevuto correttamente, tutti gli endpoint restituiscono un errore di trasmissione oppure un endpoint restituisce un errore che non riguarda la trasmissione.
Negli esempi seguenti viene configurato il servizio di routing per l'uso di un elenco di backup.
<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 does not respond (which the first endpoint won't
//since the client does not exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);
Modelli di errore supportati
Nella tabella seguente vengono descritti i modelli compatibili con l'uso degli elenchi di endpoint di backup, insieme alle note che descrivono i dettagli della gestione degli errori per modelli specifici.
Modello | Sessione | Transazione | Ricevi contesto | Elenco di backup supportato | Note |
---|---|---|---|---|---|
One-Way | Sì | Tenta di inviare di nuovo il messaggio in un endpoint di backup. Se il messaggio è multicast, solo il messaggio nel canale non riuscito viene spostato nella destinazione di backup. | |||
One-Way | ✔️ | NO | Viene generata un'eccezione e viene eseguito il rollback della transazione. | ||
One-Way | ✔️ | Sì | Tenta di inviare di nuovo il messaggio in un endpoint di backup. Dopo la corretta ricezione del messaggio, completare tutti i contesti di ricezione del messaggio. Se il messaggio non viene ricevuto con successo da alcun endpoint, non completare il contesto di ricezione. Quando questo messaggio è multicast, il contesto di ricezione viene completato solo se il messaggio viene ricevuto correttamente da almeno un endpoint (primario o backup). Se nessuno degli endpoint in uno dei percorsi multicast riceve correttamente il messaggio, non completare il contesto di ricezione. |
||
One-Way | ✔️ | ✔️ | Sì | Interrompere la transazione precedente, creare una nuova transazione e inviare nuovamente tutti i messaggi. I messaggi che hanno rilevato un errore vengono trasmessi a una destinazione di backup. Dopo aver creato una transazione in cui tutte le trasmissioni hanno esito positivo, completare i contesti di ricezione ed eseguire il commit della transazione. |
|
One-Way | ✔️ | Sì | Tenta di inviare di nuovo il messaggio in un endpoint di backup. In uno scenario multicast vengono restituiti di nuovo alle destinazioni di backup solo i messaggi in una sessione che hanno rilevato un errore o in una sessione la cui chiusura della sessione non è riuscita. | ||
One-Way | ✔️ | ✔️ | NO | Viene generata un'eccezione e viene eseguito il rollback della transazione. | |
One-Way | ✔️ | ✔️ | Sì | Tenta di inviare di nuovo il messaggio in un endpoint di backup. Dopo che tutti i messaggi vengono inviati senza errori, la sessione indica che non sono più presenti messaggi e il servizio di routing chiude correttamente tutti i canali di sessione in uscita, tutti i contesti di ricezione vengono completati e il canale della sessione in ingresso viene chiuso. | |
One-Way | ✔️ | ✔️ | ✔️ | Sì | Interrompere la transazione corrente e crearne una nuova. Inviare nuovamente tutti i messaggi precedenti nella sessione. Dopo la creazione di una transazione in cui tutti i messaggi sono stati inviati correttamente e la sessione indica che non sono più presenti messaggi, tutti i canali di sessione in uscita vengono chiusi, i contesti di ricezione vengono tutti completati con la transazione, il canale della sessione in ingresso viene chiuso e viene eseguito il commit della transazione. Quando le sessioni vengono multicast, i messaggi senza errori vengono inviati nuovamente alla stessa destinazione di prima e i messaggi che hanno rilevato un errore vengono inviati alle destinazioni di backup. |
Two-Way | Sì | Inviare a una destinazione di backup. Dopo che un canale restituisce un messaggio di risposta, restituire la risposta al client originale. | |||
Two-Way | ✔️ | Sì | Inviare tutti i messaggi nel canale a una destinazione di backup. Dopo che un canale restituisce un messaggio di risposta, restituire la risposta al client originale. | ||
Two-Way | ✔️ | NO | Viene generata un'eccezione e viene eseguito il rollback della transazione. | ||
Two-Way | ✔️ | ✔️ | NO | Viene generata un'eccezione e viene eseguito il rollback della transazione. | |
Duplex | NO | La comunicazione duplex non sessione non è attualmente supportata. | |||
Duplex | ✔️ | Sì | Inviare a una destinazione di backup. |
Servizi di hosting
Poiché il servizio di routing viene implementato come servizio WCF, deve essere self-hosted all'interno di un'applicazione o ospitato da IIS o WAS. È consigliabile ospitare il servizio di routing in IIS, WAS o in un'applicazione del servizio Windows per sfruttare le funzionalità di gestione automatica dell'avvio e del ciclo di vita disponibili in questi ambienti di hosting.
Nell'esempio seguente viene illustrato l'hosting del servizio di routing in un'applicazione.
using (ServiceHost serviceHost =
new ServiceHost(typeof(RoutingService)))
Per ospitare il servizio di routing in IIS o WAS, è necessario creare un file di servizio (con estensione svc) o usare l'attivazione basata sulla configurazione del servizio. Quando si usa un file di servizio, è necessario specificare RoutingService utilizzando il parametro Service. L'esempio seguente contiene un file di servizio di esempio che può essere usato per ospitare il servizio di routing 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" %>
Servizio di routing e impersonificazione
Il servizio di routing WCF può essere usato con l'impersonificazione per l'invio e la ricezione di messaggi. Si applicano tutti i soliti vincoli di impersonificazione di Windows. Se fosse stato necessario configurare le autorizzazioni del servizio o dell'account per usare impersonazione durante la scrittura del proprio servizio, sarà necessario eseguire quegli stessi passaggi per usare l'impersonazione con il servizio di routing. Per altre informazioni, vedere Delega e rappresentazione.
L'impersonificazione con il servizio di routing richiede l'uso dell'impersonificazione di ASP.NET mentre si è in modalità di compatibilità di ASP.NET o delle credenziali di Windows configurate per consentire l'impersonificazione. Per altre informazioni sulla modalità di compatibilità ASP.NET, vedere Servizi WCF e ASP.NET.
Avvertimento
Il servizio di routing WCF non supporta l'impersonificazione con l'autenticazione semplice.
Per utilizzare l'impersonificazione di ASP.NET con il servizio di routing, abilita la modalità di compatibilità ASP.NET nell'ambiente di hosting del servizio. Il servizio di routing è già stato contrassegnato come compatibile con la modalità ASP.NET e l'impersonificazione sarà abilitata automaticamente. La impersonificazione è l'unico uso supportato nell'integrazione di ASP.NET con il servizio di routing.
Per usare la rappresentazione delle credenziali di Windows con il servizio di routing, è necessario configurare sia le credenziali che il servizio. L'oggetto credenziali client (WindowsClientCredential, accessibile da ChannelFactory) definisce una proprietà AllowedImpersonationLevel che deve essere impostata per consentire l'impersonificazione. Infine, nel servizio è necessario configurare il comportamento di ServiceAuthorizationBehavior per impostare ImpersonateCallerForAllOperations
su true
. Il servizio di routing usa questo flag per decidere se creare i client per l'inoltro dei messaggi con l'impersonificazione abilitata.