设计模式:基于列表的发布-订阅
ListBasedPublishSubscribe 示例演示作为 Windows Communication Foundation (WCF) 程序实现的基于列表的发布-订阅模式。
注意
本主题的最后介绍了此示例的设置过程和生成说明。
Microsoft 模式和实践出版物 Integration Patterns(集成模式)中对基于列表的发布-订阅设计模式进行了说明。 发布-订阅模式可以向已经订阅某一信息主题的接收者群体传递信息。 基于列表的发布-订阅可维护一份订户列表。 如果有要共享的信息,则会向列表上的每个订户发送一份副本。 本示例演示基于列表的动态发布-订阅模式,在此模式下客户端可以根据需要随时订阅或取消订阅。
基于列表的发布-订阅示例由客户端、服务和数据源程序组成。 可以有多个客户端和多个数据源程序同时运行。 客户端订阅服务、接收通知,然后取消订阅。 数据源程序向服务发送将与所有当前订户共享的信息。
在本示例中,客户端和数据源是控制台程序(.exe 文件),而服务是 Internet 信息服务 (IIS) 所承载的库 (.dll)。 客户端和数据源活动在桌面上可见。
服务使用双工通信。 ISampleContract
服务协定与 ISampleClientCallback
回调协定成对出现。 服务实现 Subscribe 和 Unsubscribe 服务操作,客户端使用这些操作加入或离开订户列表。 服务还实现 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 可以关闭客户端。
设置和生成示例
若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照 Building the Windows Communication Foundation Samples中的说明进行操作。
在同一计算机上运行示例
使用浏览器,通过输入以下地址来测试是否可以访问该服务:
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。