复习:在上一篇我介绍了MSF的基本订阅,模式就是,客户端A,订阅服务器。客户端B,订阅服务器。通过服务器广播消息,
所有订阅过的客户端都能接到消息。
进阶:在上一篇的基础上,增加客户端A,发送信息到服务器,服务器把接到的信息,再转发给所有订阅了的客户端。
传送门:框架的获取 http://www.cnblogs.com/bluedoctor/
医生的博客:http://www.pwmis.com/sqlmap/
正文:首先启动服务器,再单击按钮,给所有监听客户端,发送消息。按钮事件的代码如下:
ServiceRequest request = new ServiceRequest(); request.ServiceName = "TestSendALLClient"; request.MethodName = "SendMsg"; request.Parameters = new object[] {txtsend.Text}; //异步方式测试 Proxy serviceProxy = new Proxy(); serviceProxy.ErrorMessage += new EventHandler<MessageSubscriber.MessageEventArgs>(serviceProxy_ErrorMessage); serviceProxy.ServiceBaseUri = this.txtSerivceUri.Text; int msgId = serviceProxy.Subscribe<string>(request, DataType.Text, (converter) => { if (converter.Succeed) { MyInvoke(this, () => { this.lblResult.Text = converter.Result.ToString(); }); } else { MessageBox.Show(converter.ErrorMessage); } }); if (msgId < 1) { MessageBox.Show("订阅失败"); } else { this.btnServerTime.Enabled = false; } }
重点看一下这里的发送消息给服务器,ServiceName是类的名字,MethodName 是方法的名字,Parameters 是需要传给服务器的参数。
这个类、和函数是参考订阅闹钟的的功能来做的。最后在配置文件中注册刚刚写的类。运行后,看到,客户端发送的消息,已经被服务器
接收到了,并分发给订阅的客户端了。
request.ServiceName = "TestSendALLClient"; request.MethodName = "SendMsg"; request.Parameters = new object[] {txtsend.Text};
public ServiceEventSource SendMsg(string msg) { return new ServiceEventSource(timer,2,() => { //要初始化执行的代码或者方法 //publishCount = 0; //this.AlarmTime = targetTime; //timer.Start(); CurrentContext.PublishData(msg); //如果上面的代码是一个执行时间比较长的方法,但又不知道何时执行完成, //并且不想等待超时回收服务对象,而是在执行完成后立即回收服务对象,可以调用下面的代码: //CurrentContext.PublishEventSource.DeActive(); //注意:调用DeActive 方法后将会停止事件推送,所以请注意此方法调用的时机。 //下面代码仅做测试,查看服务事件源对象的活动生命周期 //在 ActiveLife 时间之后,一直没有事件推送,则事件源对象被视为非活动状态,发布工作线程会被回收。 //在本例中,ActiveLife 为ServiceEventSource 构造函数的第二个参数,值为 2分钟,可以通过下面一行代码证实: int life = CurrentContext.PublishEventSource.ActiveLife; //如果上面执行的是一个执行时间比较长的方法,并且有返回值,想将返回值也推送给订阅端,可以再次执行CurrentContext.PublishData //CurrentContext.PublishData(DateTime.Now); //如果事件推送结束,需要设置事件源为非活动状态,否则,需要等待 ActiveLife 时间之后自然过期成为非活动状态。 //如果你无法确定事件推送何时结束,请不要调用下面的方法 //CurrentContext.PublishEventSource.DeActive(); }); }
<Add Key="TestSendALLClient" InterfaceName="IService" FullClassName="ServiceSample.TestSendALLClient" Assembly="ServiceSample" />