简单的WCF发布-订阅(Pub/Sub)服务
2008-09-02 01:56
274 查看
简单的WCF发布-订阅(Pub/Sub)服务
发布-订阅服务架构是分布式系统中常见的服务架构。本文将通过一个简单的例子介绍WCF中发布-订阅服务的实现,以及一些相关概念的介绍。
WCF支持回调操作,所谓回调就是服务端调用客户端的操作。如下图所示,在回调时:服务成为客户端,客户端成为服务。
本文要实现的例子是这样的:客户端(订阅者)向服务(发布者)提出订阅请求,服务响应客户端请求,并通过回调客户端上的操作来通知客户端。
一、契约
所谓契约就是大家都有遵守的东西。发布-订阅模式的契约和其他回调服务一样分为两个部分:服务契约和回调契约。
1.1 服务契约
[ServiceContract(CallbackContract=typeof(ICallbackEvents))]
public interface IPublishService
{
[OperationContract(IsOneWay=true)]
void Subscribe(Guid id);
[OperationContract(IsOneWay=true)]
void UnSubscribe(Guid id);
}
服务契约提供了订阅Subscribe( )和退订UnSubscibe( )两个服务操作。两个操作的参数都是GUID,主要是区分各个订阅者。
将ServiceContract的CallbackContract属性定义为ICallbackEvents,即是指明回调契约。
1.2 回调契约
public interface ICallbackEvents
{
[OperationContract(IsOneWay=true)]
void Notify();
}
回调契约定义了一个Notify( )操作,是用于服务通知客户端的。
回调契约之所以不用加[ServiceContract],是因为在服务契约中已经指明了。
二、服务
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
public class PublishService : IPublishService
{
public List<Guid> list_SubscrberId = new List<Guid>();
public List<ICallbackEvents> list_Callback = new List<ICallbackEvents>();
public void Subscribe(Guid id)
{
if (list_SubscrberId.IndexOf(id) < 0)//如果不存在,则添加
{
list_SubscrberId.Add(id);
ICallbackEvents callback = OperationContext.Current.GetCallbackChannel<ICallbackEvents>();
list_Callback.Add(callback);
}
}
public void UnSubscribe(Guid id)
{
list_Callback.RemoveAt(list_SubscrberId.IndexOf(id));
list_SubscrberId.Remove(id);
}
}
服务实现了订阅Subscribe( )和退订UnSubscibe( )两个操作。并且定义了两个链表分别保存订阅者的ID和 他的回调操作的上下文。两个链表的项是依次对应的。其中,ID链表是和下面的主机进程的ListBox是“绑定”。
需要强调的是,我们在这把ServiceBehavior设为可重入的来实现回调功能。将其实例模式设置为单例模式,以让多个订阅者公用一个发布者。
三、主机
public partial class PublishForm : Form
{
private PubSub_Srv.PublishService pubsrv = new PubSub_Srv.PublishService();
private ServiceHost host;
public PublishForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
host = new ServiceHost(pubsrv);
host.Open();
}
private void btn_Stop_Click(object sender, EventArgs e)
{
host.Close();
}
private void btn_NotifyAll_Click(object sender, EventArgs e)
{
for (int i = 0; i < pubsrv.list_SubscrberId.Count; i++)
{
try
{
pubsrv.list_Callback[i].Notify();
}
catch(Exception ex)
{
MessageBox.Show(ex.Data.ToString()+"/n无法连接客户:/n"+pubsrv.list_SubscrberId[i].ToString());
}
}
}
private void btn_Refresh_Click(object sender, EventArgs e)
{
listBox_SubsciberID.Items.Clear();
for (int i = 0; i < pubsrv.list_SubscrberId.Count; i++)
listBox_SubsciberID.Items.Add(pubsrv.list_SubscrberId[i].ToString());
}
}
主机进程是一个WindowsForm的应用程序,提供服务的承载和图像界面。
四、客户端
public partial class SubsciberForm : Form
{
private Guid Myid;
private PubSub_Srv_Ref.PublishServiceClient client;
public SubsciberForm()
{
InitializeComponent();
Myid = System.Guid.NewGuid();
this.Text = Myid.ToString();
CallbackEvents callback = new CallbackEvents();
InstanceContext context = new InstanceContext(callback);
client = new Subscriber.PubSub_Srv_Ref.PublishServiceClient(context);
}
private void SubsciberForm_Load(object sender, EventArgs e)
{
}
private void btn_Subscibe_Click(object sender, EventArgs e)
{
if (client == null)
{
CallbackEvents callback = new CallbackEvents();
InstanceContext context = new InstanceContext(callback);
client = new Subscriber.PubSub_Srv_Ref.PublishServiceClient(context);
}
client.Subscribe(Myid);
}
private void btn_UnSubscibe_Click(object sender, EventArgs e)
{
client.UnSubscribe(Myid);
client.Close();
}
}
五、配置
最后要说明的是,要实现回调服务必须使用具有双向通信功能的绑定方式,如netTcpBinding。
另外为了在为了在网络上运行,需要将<security mode="None">
本文代码下载:http://download.csdn.net/source/605896
发布-订阅服务架构是分布式系统中常见的服务架构。本文将通过一个简单的例子介绍WCF中发布-订阅服务的实现,以及一些相关概念的介绍。
WCF支持回调操作,所谓回调就是服务端调用客户端的操作。如下图所示,在回调时:服务成为客户端,客户端成为服务。
本文要实现的例子是这样的:客户端(订阅者)向服务(发布者)提出订阅请求,服务响应客户端请求,并通过回调客户端上的操作来通知客户端。
一、契约
所谓契约就是大家都有遵守的东西。发布-订阅模式的契约和其他回调服务一样分为两个部分:服务契约和回调契约。
1.1 服务契约
[ServiceContract(CallbackContract=typeof(ICallbackEvents))]
public interface IPublishService
{
[OperationContract(IsOneWay=true)]
void Subscribe(Guid id);
[OperationContract(IsOneWay=true)]
void UnSubscribe(Guid id);
}
服务契约提供了订阅Subscribe( )和退订UnSubscibe( )两个服务操作。两个操作的参数都是GUID,主要是区分各个订阅者。
将ServiceContract的CallbackContract属性定义为ICallbackEvents,即是指明回调契约。
1.2 回调契约
public interface ICallbackEvents
{
[OperationContract(IsOneWay=true)]
void Notify();
}
回调契约定义了一个Notify( )操作,是用于服务通知客户端的。
回调契约之所以不用加[ServiceContract],是因为在服务契约中已经指明了。
二、服务
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
public class PublishService : IPublishService
{
public List<Guid> list_SubscrberId = new List<Guid>();
public List<ICallbackEvents> list_Callback = new List<ICallbackEvents>();
public void Subscribe(Guid id)
{
if (list_SubscrberId.IndexOf(id) < 0)//如果不存在,则添加
{
list_SubscrberId.Add(id);
ICallbackEvents callback = OperationContext.Current.GetCallbackChannel<ICallbackEvents>();
list_Callback.Add(callback);
}
}
public void UnSubscribe(Guid id)
{
list_Callback.RemoveAt(list_SubscrberId.IndexOf(id));
list_SubscrberId.Remove(id);
}
}
服务实现了订阅Subscribe( )和退订UnSubscibe( )两个操作。并且定义了两个链表分别保存订阅者的ID和 他的回调操作的上下文。两个链表的项是依次对应的。其中,ID链表是和下面的主机进程的ListBox是“绑定”。
需要强调的是,我们在这把ServiceBehavior设为可重入的来实现回调功能。将其实例模式设置为单例模式,以让多个订阅者公用一个发布者。
三、主机
public partial class PublishForm : Form
{
private PubSub_Srv.PublishService pubsrv = new PubSub_Srv.PublishService();
private ServiceHost host;
public PublishForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
host = new ServiceHost(pubsrv);
host.Open();
}
private void btn_Stop_Click(object sender, EventArgs e)
{
host.Close();
}
private void btn_NotifyAll_Click(object sender, EventArgs e)
{
for (int i = 0; i < pubsrv.list_SubscrberId.Count; i++)
{
try
{
pubsrv.list_Callback[i].Notify();
}
catch(Exception ex)
{
MessageBox.Show(ex.Data.ToString()+"/n无法连接客户:/n"+pubsrv.list_SubscrberId[i].ToString());
}
}
}
private void btn_Refresh_Click(object sender, EventArgs e)
{
listBox_SubsciberID.Items.Clear();
for (int i = 0; i < pubsrv.list_SubscrberId.Count; i++)
listBox_SubsciberID.Items.Add(pubsrv.list_SubscrberId[i].ToString());
}
}
主机进程是一个WindowsForm的应用程序,提供服务的承载和图像界面。
四、客户端
public partial class SubsciberForm : Form
{
private Guid Myid;
private PubSub_Srv_Ref.PublishServiceClient client;
public SubsciberForm()
{
InitializeComponent();
Myid = System.Guid.NewGuid();
this.Text = Myid.ToString();
CallbackEvents callback = new CallbackEvents();
InstanceContext context = new InstanceContext(callback);
client = new Subscriber.PubSub_Srv_Ref.PublishServiceClient(context);
}
private void SubsciberForm_Load(object sender, EventArgs e)
{
}
private void btn_Subscibe_Click(object sender, EventArgs e)
{
if (client == null)
{
CallbackEvents callback = new CallbackEvents();
InstanceContext context = new InstanceContext(callback);
client = new Subscriber.PubSub_Srv_Ref.PublishServiceClient(context);
}
client.Subscribe(Myid);
}
private void btn_UnSubscibe_Click(object sender, EventArgs e)
{
client.UnSubscribe(Myid);
client.Close();
}
}
五、配置
最后要说明的是,要实现回调服务必须使用具有双向通信功能的绑定方式,如netTcpBinding。
另外为了在为了在网络上运行,需要将<security mode="None">
本文代码下载:http://download.csdn.net/source/605896
相关文章推荐
- 简单的WCF发布-订阅(Pub/Sub)服务(转)
- 基于WCF和MSMQ构建发布/订阅消息总线(Pub/Sub Message Bus) 推荐
- 基于WCF和MSMQ构建发布/订阅消息总线(Pub/Sub Message Bus)
- 开发创建XMPP“发布订阅”扩展(xmpp pubsub extend)
- ASP.NET 创建发布一个简单的wcf服务
- zeroMQ初体验-2.发布订阅模式(pub/sub)
- Redis源码分析(十七)——订阅与发布PubSub
- Redis命令学习-Pub/Sub(发布/订阅)
- linux下使用hiredis异步API实现sub/pub消息订阅和发布的功能 标签: hiredishiredis异步APIhiredis事件处理redis消息订阅发布redis c接口 2016-
- 发布/订阅(Pub/Sub)
- php redis pub/sub(Publish/Subscribe,发布/订阅的信息系统)之基本使用
- zeromq/jzmq pub/sub发布订阅java代码
- redis源码分析之发布订阅(pub/sub)
- redis的发布订阅模式pubsub
- redis 高级应用之二(Redis的持久化 和 消息的[pub/sub]发布和订阅)
- linux下使用hiredis异步API实现sub/pub消息订阅和发布的功能
- redis命令详解与使用场景举例——Pub与Sub(发布订阅)
- php redis pub/sub(Publish/Subscribe,发布/订阅的信息系统)之基本使用
- Redis的发布/订阅(pub/sub)
- 【Redis】Java实现redis消息订阅/发布(PubSub)