Designmönster: Listbaserad publiceringsprenumerering
Exemplet ListBasedPublishSubscribe visar det listbaserade mönstret Publish-Subscribe som implementerats som ett WCF-program (Windows Communication Foundation).
Kommentar
Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.
Det listbaserade designmönstret Publicera prenumeration beskrivs i publikationen Microsoft Patterns &Practices, Integration Patterns. Mönstret Publicera prenumeration skickar information till en samling mottagare som prenumererar på ett informationsämne. Listbaserad publiceringsprenumerering har en lista över prenumeranter. När det finns information att dela skickas en kopia till varje prenumerant i listan. Det här exemplet visar ett dynamiskt listbaserat mönster för publicering och prenumeration, där klienter kan prenumerera eller avbryta prenumerationen så ofta som det behövs.
Det listbaserade exemplet Publish-Subscribe består av en klient, en tjänst och ett datakällasprogram. Det kan finnas fler än en klient och fler än ett datakällaprogram som körs. Klienter prenumererar på tjänsten, tar emot meddelanden och avbryter prenumerationen. Datakällans program skickar information till tjänsten som ska delas med alla aktuella prenumeranter.
I det här exemplet är klienten och datakällan konsolprogram (.exe filer) och tjänsten är ett bibliotek (.dll) som finns i Internet Information Services (IIS). Klient- och datakällans aktivitet visas på skrivbordet.
Tjänsten använder duplex-kommunikation. Tjänstkontraktet ISampleContract
är kopplat till ett ISampleClientCallback
återanropskontrakt. Tjänsten implementerar prenumerations- och avprenumerationstjänståtgärder, som klienter använder för att ansluta till eller lämna listan över prenumeranter. Tjänsten implementerar också tjänståtgärden PublishPriceChange
, som datakällan anropar för att tillhandahålla tjänsten med ny information. Klientprogrammet implementerar tjänståtgärden PriceChange
, som tjänsten anropar för att meddela alla prenumeranter om en prisändring.
// 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);
}
Tjänsten använder en .NET Framework-händelse som mekanism för att informera alla prenumeranter om ny information. När en klient ansluter till tjänsten genom att anropa Prenumerera tillhandahåller den en händelsehanterare. När en klient lämnar, avregistrerar den sin händelsehanterare från händelsen. När en datakälla anropar tjänsten för att rapportera en prisändring genererar tjänsten händelsen. Detta anropar varje instans av tjänsten, en för varje klient som har prenumererat och gör att deras händelsehanterare körs. Varje händelsehanterare skickar informationen till klienten via dess återanropsfunktion.
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);
}
}
När du kör exemplet startar du flera klienter. Klienterna prenumererar på tjänsten. Kör sedan datakällans program, som skickar information till tjänsten. Tjänsten vidarebefordrar informationen till alla prenumeranter. Du kan se aktivitet på varje klientkonsol som bekräftar att informationen har tagits emot. Tryck på RETUR i klientfönstret för att stänga av klienten.
Så här konfigurerar och skapar du exemplet
Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.
Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.
Så här kör du exemplet på samma dator
Testa att du kan komma åt tjänsten med hjälp av en webbläsare genom att ange följande adress:
http://localhost/servicemodelsamples/service.svc
. En bekräftelsesida ska visas som svar.Kör Client.exe från \client\bin\, från under den språkspecifika mappen. Klientaktiviteten visas i klientkonsolfönstret. Starta flera klienter.
Kör Datasource.exe från \datasource\bin\, från under den språkspecifika mappen. Datakällaktiviteten visas i konsolfönstret. När datakällan skickar information till tjänsten ska den skickas till varje klient.
Om klienten, datakällan och tjänstprogrammen inte kan kommunicera kan du läsa Felsökningstips för WCF-exempel.
Så här kör du exemplet mellan datorer
Konfigurera tjänstdatorn:
På tjänstdatorn skapar du en virtuell katalog med namnet ServiceModelSamples. Batchfilen Setupvroot.bat från engångsinstallationsproceduren för Windows Communication Foundation-exempel kan användas för att skapa diskkatalogen och den virtuella katalogen.
Kopiera tjänstprogramfilerna från %SystemDrive%\Inetpub\wwwroot\servicemodelsamples till den virtuella katalogen ServiceModelSamples på tjänstdatorn. Se till att inkludera filerna i katalogen \bin.
Testa att du kan komma åt tjänsten från klientdatorn med hjälp av en webbläsare.
Konfigurera klientdatorerna:
Kopiera klientprogramfilerna från mappen \client\bin\ under den språkspecifika mappen till klientdatorerna.
I varje klientkonfigurationsfil ändrar du adressvärdet för slutpunktsdefinitionen så att den matchar den nya adressen för din tjänst. Ersätt alla referenser till "localhost" med ett fullständigt domännamn i adressen.
Konfigurera datakälldatorn:
Kopiera datakällprogramfilerna från mappen \datasource\bin\ under den språkspecifika mappen till datakälldatorn.
I konfigurationsfilen för datakällan ändrar du adressvärdet för slutpunktsdefinitionen så att det matchar den nya adressen för din tjänst. Ersätt alla referenser till "localhost" med ett fullständigt domännamn i adressen.
Starta Client.exe från en kommandotolk på klientdatorerna.
Starta Datasource.exe från en kommandotolk på datakälldatorn.