Condividi tramite


Filtro messaggi personalizzato

L'esempio MessageFilter illustra come sostituire i filtri messaggi usati da Windows Communication Foundation (WCF) per inviare messaggi agli endpoint.

Annotazioni

La procedura di installazione e le istruzioni di compilazione per questo esempio si trovano alla fine di questo argomento.

Quando il primo messaggio in un canale arriva al server, il server deve determinare quale (se presente) degli endpoint associati a tale URI deve ricevere il messaggio. Questo processo è controllato dagli MessageFilter oggetti associati all'oggetto EndpointDispatcher.

Ogni endpoint di un servizio ha un singolo EndpointDispatcher. l'oggetto EndpointDispatcher ha sia un oggetto AddressFilter che un oggetto ContractFilter. L'unione di questi due filtri è il filtro dei messaggi usato per tale endpoint.

Per impostazione predefinita, il AddressFilter di un endpoint corrisponde a qualsiasi messaggio indirizzato a un servizio endpoint con indirizzo corrispondente a EndpointAddress. Per impostazione predefinita, un endpoint ispeziona l'azione del messaggio in arrivo e abbina qualsiasi messaggio con un'azione che corrisponde a una delle azioni delle operazioni del contratto dell'endpoint di servizio (vengono considerate solo le azioni ContractFilterIsInitiating=). Di conseguenza, per impostazione predefinita, il filtro per un endpoint corrisponde solo se l'intestazione To del messaggio corrisponde all'EndpointAddress dell'endpoint e l'azione del messaggio corrisponde a una delle azioni dell'operazione dell'endpoint.

Questi filtri possono essere modificati usando un comportamento. Nell'esempio il servizio crea un oggetto IEndpointBehavior che sostituisce AddressFilter e ContractFilter in EndpointDispatcher:

class FilteringEndpointBehavior : IEndpointBehavior
{
    //...
}

Vengono definiti due filtri di indirizzi:

// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter { }
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter { }

Il FilteringEndpointBehavior è reso configurabile e consente due diverse varianti.

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }

La variante 1 corrisponde solo a indirizzi che contengono un 'e' (ma che hanno un'azione), mentre la variante 2 corrisponde solo a indirizzi che non dispongono di un 'e':

if (Variation == 1)
    return new FilteringEndpointBehavior(
        new MatchEAddressFilter(), new MatchAllMessageFilter());
else
    return new FilteringEndpointBehavior(
        new MatchNoEAddressFilter(), new MatchAllMessageFilter());

Nel file di configurazione il servizio registra il nuovo comportamento:

<extensions>
    <behaviorExtensions>
        <add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
    </behaviorExtensions>
</extensions>

Il servizio crea endpointBehavior quindi le configurazioni per ogni variante:

<endpointBehaviors>
    <behavior name="endpoint1">
        <filteringEndpointBehavior variation="1" />
    </behavior>
    <behavior name="endpoint2">
        <filteringEndpointBehavior variation="2" />
    </behavior>
</endpointBehaviors>

Infine, l'endpoint del servizio fa riferimento a uno di behaviorConfigurations:

<endpoint address=""
        bindingConfiguration="ws"
        listenUri=""
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.IHello"
        behaviorConfiguration="endpoint2" />

L'implementazione dell'applicazione client è semplice; crea due canali all'URI del servizio (passando tale valore come secondo parametro (via) a CreateChannel(EndpointAddress) e invia un singolo messaggio in ogni canale, ma usa indirizzi endpoint diversi per ognuno. Di conseguenza, i messaggi in uscita dal client hanno designazioni To diverse e il server risponde di conseguenza, come illustrato dall'output del client:

Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

Sending message to urn:a...
Hello

Se si modifica la variazione nel file di configurazione del server, il filtro viene sostituito e il client osserva il comportamento opposto (il messaggio a urn:e ha successo, mentre il messaggio a urn:a fallisce).

<endpoint address=""
          bindingConfiguration="ws"
          listenUri=""
          binding="wsHttpBinding"
          contract="Microsoft.ServiceModel.Samples.IHello"
          behaviorConfiguration="endpoint1" />

Per configurare, compilare ed eseguire l'esempio

  1. Per compilare la soluzione, seguire le istruzioni riportate in Compilazione degli esempi di Windows Communication Foundation.

  2. Per eseguire l'esempio in una configurazione a computer singolo, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.

  3. Per eseguire l'esempio in una configurazione tra computer, seguire le istruzioni in Esecuzione degli esempi di Windows Communication Foundation e modificare la riga seguente in Client.cs.

    Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
    

    Sostituire localhost con il nome del server.

    Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");