Delen via


Ontwerppatronen: Publiceren-abonneren op basis van lijst

Het voorbeeld ListBasedPublishSubscribe illustreert het patroon Publiceren-abonneren op basis van lijst dat is geïmplementeerd als een WCF-programma (Windows Communication Foundation).

Notitie

De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.

Het ontwerppatroon Publiceren-abonneren op basis van lijst wordt beschreven in de publicatie Microsoft Patterns & Practices, Integration Patterns. Het patroon Publish-Subscribe geeft informatie door aan een verzameling geadresseerden die zich hebben geabonneerd op een informatieonderwerp. Publiceren-abonneren op basis van een lijst houdt een lijst met abonnees bij. Wanneer er informatie is om te delen, wordt er een kopie verzonden naar elke abonnee in de lijst. In dit voorbeeld ziet u een dynamisch patroon voor publiceren/abonneren op basis van een lijst, waarbij clients zich zo vaak kunnen abonneren of afmelden als nodig is.

Het voorbeeld Publiceren-abonneren op basis van lijst bestaat uit een client, een service en een gegevensbronprogramma. Er kunnen meer dan één client en meer dan één gegevensbronprogramma worden uitgevoerd. Clients abonneren zich op de service, ontvangen meldingen en afmelden. Gegevensbronprogramma's verzenden informatie naar de service die moet worden gedeeld met alle huidige abonnees.

In dit voorbeeld zijn de client- en gegevensbron consoleprogramma's (.exe bestanden) en de service is een bibliotheek (.dll) die wordt gehost in Internet Information Services (IIS). Client- en gegevensbronactiviteit zijn zichtbaar op het bureaublad.

De service maakt gebruik van dubbelzijdige communicatie. Het ISampleContract servicecontract is gekoppeld aan een ISampleClientCallback callback-contract. De service implementeert servicebewerkingen voor abonneren en afmelden, die clients gebruiken om deel te nemen aan of de lijst met abonnees te verlaten. De service implementeert ook de PublishPriceChange servicebewerking, die door het gegevensbronprogramma wordt aanroepen om de service nieuwe informatie te bieden. Het clientprogramma implementeert de PriceChange servicebewerking, die de service aanroept om alle abonnees op de hoogte te stellen van een prijswijziging.

// Create a service contract and define the service operations.
// NOTE: The service operations must be declared explicitly.
[ServiceContract(SessionMode=SessionMode.Required,
      CallbackContract=typeof(ISampleClientContract))]
public interface ISampleContract
{
    [OperationContract(IsOneWay = false, IsInitiating=true)]
    void Subscribe();
    [OperationContract(IsOneWay = false, IsTerminating=true)]
    void Unsubscribe();
    [OperationContract(IsOneWay = true)]
    void PublishPriceChange(string item, double price,
                                     double change);
}

public interface ISampleClientContract
{
    [OperationContract(IsOneWay = true)]
    void PriceChange(string item, double price, double change);
}

De service gebruikt een .NET Framework-gebeurtenis als mechanisme om alle abonnees te informeren over nieuwe informatie. Wanneer een client lid wordt van de service door Abonneren aan te roepen, biedt deze een gebeurtenis-handler. Wanneer een client vertrekt, wordt de gebeurtenis-handler van de gebeurtenis afgemeld. Wanneer een gegevensbron de service aanroept om een prijswijziging te rapporteren, wordt de gebeurtenis gegenereerd door de service. Hiermee wordt elk exemplaar van de service aangeroepen, één voor elke client die is geabonneerd en worden de gebeurtenis-handlers uitgevoerd. Elke gebeurtenis-handler geeft de informatie door aan de client via de callback-functie.

public class PriceChangeEventArgs : EventArgs
    {
        public string Item;
        public double Price;
        public double Change;
    }

    // The Service implementation implements your service contract.
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
    public class SampleService : ISampleContract
    {
        public static event PriceChangeEventHandler PriceChangeEvent;
        public delegate void PriceChangeEventHandler(object sender, PriceChangeEventArgs e);

        ISampleClientContract callback = null;

        PriceChangeEventHandler priceChangeHandler = null;

        //Clients call this service operation to subscribe.
        //A price change event handler is registered for this client instance.

        public void Subscribe()
        {
            callback = OperationContext.Current.GetCallbackChannel<ISampleClientContract>();
            priceChangeHandler = new PriceChangeEventHandler(PriceChangeHandler);
            PriceChangeEvent += priceChangeHandler;
        }

        //Clients call this service operation to unsubscribe.
        //The previous price change event handler is unregistered.

        public void Unsubscribe()
        {
            PriceChangeEvent -= priceChangeHandler;
        }

        //Information source clients call this service operation to report a price change.
        //A price change event is raised. The price change event handlers for each subscriber will execute.

        public void PublishPriceChange(string item, double price, double change)
        {
            PriceChangeEventArgs e = new PriceChangeEventArgs();
            e.Item = item;
            e.Price = price;
            e.Change = change;
            PriceChangeEvent(this, e);
        }

        //This event handler runs when a PriceChange event is raised.
        //The client's PriceChange service operation is invoked to provide notification about the price change.

        public void PriceChangeHandler(object sender, PriceChangeEventArgs e)
        {
            callback.PriceChange(e.Item, e.Price, e.Change);
        }

    }

Wanneer u het voorbeeld uitvoert, start u verschillende clients. De clients abonneren zich op de service. Voer vervolgens het gegevensbronprogramma uit, waarmee informatie naar de service wordt verzonden. De service geeft de informatie door aan alle abonnees. U kunt activiteit op elke clientconsole zien om te bevestigen dat de informatie is ontvangen. Druk op Enter in het clientvenster om de client af te sluiten.

Het voorbeeld instellen en bouwen

  1. Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.

  2. Als u de C# of Visual Basic .NET-editie van de oplossing wilt bouwen, volgt u de instructies in het bouwen van de Windows Communication Foundation-voorbeelden.

Het voorbeeld uitvoeren op dezelfde computer

  1. Test of u toegang hebt tot de service met behulp van een browser door het volgende adres in te voeren: http://localhost/servicemodelsamples/service.svc Er moet een bevestigingspagina worden weergegeven als antwoord.

  2. Voer Client.exe uit vanuit \client\bin\, vanuit de taalspecifieke map. Clientactiviteit wordt weergegeven in het clientconsolevenster. Start verschillende clients.

  3. Voer Datasource.exe uit vanuit \datasource\bin\, vanuit de taalspecifieke map. Gegevensbronactiviteit wordt weergegeven in het consolevenster. Zodra de gegevensbron informatie naar de service verzendt, moet deze worden doorgegeven aan elke client.

  4. Als de client-, gegevensbron- en serviceprogramma's niet kunnen communiceren, raadpleegt u Tips voor probleemoplossing voor WCF-voorbeelden.

Het voorbeeld uitvoeren op verschillende computers

  1. De servicemachine instellen:

    1. Maak op de servicemachine een virtuele map met de naam ServiceModelSamples. Het batchbestand Setupvroot.bat uit de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden kan worden gebruikt om de schijfmap en virtuele map te maken.

    2. Kopieer de serviceprogrammabestanden van %SystemDrive%\Inetpub\wwwroot\servicemodelsamples naar de virtuele map ServiceModelSamples op de servicecomputer. Zorg ervoor dat u de bestanden in de map \bin opneemt.

    3. Test of u toegang hebt tot de service vanaf de clientcomputer met behulp van een browser.

  2. Stel de clientcomputers in:

    1. Kopieer de clientprogrammabestanden uit de map \client\bin\ onder de taalspecifieke map naar de clientcomputers.

    2. Wijzig in elk clientconfiguratiebestand de adreswaarde van de eindpuntdefinitie zodat deze overeenkomt met het nieuwe adres van uw service. Vervang alle verwijzingen naar 'localhost' door een volledig gekwalificeerde domeinnaam in het adres.

  3. De gegevensbronmachine instellen:

    1. Kopieer de programmabestanden van de gegevensbron uit de map \datasource\bin\ onder de taalspecifieke map naar de computer met gegevensbronnen.

    2. Wijzig in het configuratiebestand van de gegevensbron de adreswaarde van de eindpuntdefinitie zodat deze overeenkomt met het nieuwe adres van uw service. Vervang alle verwijzingen naar 'localhost' door een volledig gekwalificeerde domeinnaam in het adres.

  4. Start Client.exe vanaf een opdrachtprompt op de clientcomputers.

  5. Start Datasource.exe vanaf een opdrachtprompt op de computer met gegevensbronnen.