ListBasedPublishSubscribe 示例演示了作为 Windows Communication Foundation (WCF) 程序实现的基于列表的 Publish-Subscribe 模式。
注释
本示例的设置过程和生成说明位于本主题末尾。
基于列表的 Publish-Subscribe 设计模式在 Microsoft 模式和实务出版物《集成模式》中介绍。 Publish-Subscribe 模式将信息传递给已订阅信息主题的收件人集合。 基于列表的发布-订阅可维护一份订户列表。 当有要共享的信息时,会向列表中的每个订阅者发送一个副本。 此示例演示了一种基于动态列表的发布-订阅模式,客户端可以根据需要尽可能频繁地订阅或取消订阅。
基于列表的 Publish-Subscribe 示例由客户端、服务和数据源程序组成。 可以运行多个客户端和多个数据源程序。 客户端订阅服务、接收通知和取消订阅。 数据源程序将信息发送到要与所有当前订阅者共享的服务。
在此示例中,客户端和数据源是控制台程序(.exe 文件),服务是 Internet Information Services(IIS)中托管的库(.dll)。 客户端和数据源活动在桌面上可见。
该服务使用双向通信。 ISampleContract
服务协定与 ISampleClientCallback
回调协定成对出现。 该服务实现订阅和取消订阅操作,客户端使用这些操作来加入或离开订阅者列表。 该服务还实现 PublishPriceChange
服务作,数据源程序调用该服务以向服务提供新信息。 客户端程序实现 PriceChange
服务操作,服务调用该操作以通知所有订阅者价格变动。
// 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);
}
该服务使用 .NET Framework 事件作为机制来通知所有订阅者有关新信息。 客户端通过调用 Subscribe 加入服务时,会提供事件处理程序。 如果客户端离开,服务将取消其事件处理程序对事件的订阅。 当数据源调用服务来报告价格更改时,该服务将引发该事件。 这会调用服务的每个实例,为每个已订阅的客户端调用一个实例,并导致其事件处理程序执行。 每个事件处理程序通过回调函数将信息传递给其客户端。
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);
}
}
运行示例时,启动多个客户端。 客户端订阅服务。 然后运行数据源程序,该程序将信息发送到服务。 该服务会将信息传递给所有订阅者。 可以在每个客户端控制台上查看活动,确认已收到信息。 在客户端窗口中按 Enter 关闭客户端。
设置和生成示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
在同一计算机上运行示例
通过输入以下地址来测试是否可以使用浏览器访问服务:
http://localhost/servicemodelsamples/service.svc
应在响应中显示确认页。从 \client\bin\(在语言特定文件夹内)中运行 Client.exe。 客户端活动显示在客户端控制台窗口中。 启动多个客户端。
从 \datasource\bin\(在语言特定文件夹内)中运行 Datasource.exe。 数据源活动显示在控制台窗口中。 数据源向服务发送信息后,应将其传递给每个客户端。
如果客户端、数据源和服务程序无法通信,请参阅 WCF 示例的故障排除提示。
跨计算机运行示例
设置服务计算机:
在服务计算机上,创建名为 ServiceModelSamples 的虚拟目录。 Windows Communication Foundation 示例的一次性安装过程中附带的批处理文件 Setupvroot.bat 可用于创建磁盘目录和虚拟目录。
将服务程序文件从 %SystemDrive%\Inetpub\wwwroot\servicemodelsamples 复制到服务计算机上的 ServiceModelSamples 虚拟目录。 请务必在 \bin 目录中包括文件。
测试是否可以使用浏览器从客户端计算机访问服务。
设置客户端计算机:
将 \client\bin\ 文件夹中的客户端程序文件(在特定于语言的文件夹下)复制到客户端计算机。
在每个客户端配置文件中,更改终结点定义的地址值以匹配服务的新地址。 在地址中将任何对“localhost”的引用替换为一个完全限定的域名。
设置数据源计算机:
将 \datasource\bin\ 文件夹中的数据源程序文件复制到特定于语言的文件夹下,复制到数据源计算机。
在数据源配置文件中,更改终结点定义的地址值以匹配服务的新地址。 在地址中将任何对“localhost”的引用替换为一个完全限定的域名。
在客户端计算机上,从命令提示符启动 Client.exe。
在数据源计算机上,从命令提示符启动 Datasource.exe。