WCF 项目应用连载[3] - 双向通信 实例管理与服务端监控
WCF 项目应用连载[1] - 索引 - 轻量级的Log系统 - Lig Sample -序
第二节我们已经创建了Lig项目,并且能稳定工作了。现在我们来改进ILigAgent接口,实现WCF的双向通信。
3.1 双向通信
_________________________________________________________________________________
ILigAgent 增加订阅-发布 接口
3.1.1 关于订阅 – 发布
1) 发布-订阅设计模式又称观察者模式,它是软件设计模式中的一种,有一点要明白,它并不是WCF中所特有,正好相反,WCF中的双向通信只是这种模式中的一种应用。
2) WCF采用回调接口来进行双向通信,每一个服务接口允许存在有且只能存在一个回调接口。可以用ServiceContract中的CallbackContract属性进行显式声明指定定该服务接口的回调接口。
3) 回调接口由客户端实现。Server端通过一个静态的OperationContext对象获取客户端回调实例,我们用该实例在Server端调用回调接口,即可将消息发送给Client端。
OperationContext.Current.GetCallbackChannel<T>
如你所愿
1) 我们为ILigAgent增加了RegisterClient操作接口与Subcribe接口,Subcribe用于订阅服务端的消息。
2) 同时增加了ILigAgentCallback回调接口,用来在Server端实现消息推送。回调接口我们增加OnNotifyOnline,用来客户端注册成功后,Server将生成的带ClientID信息的消息发送给注册的客户端。
注意:服务端不同的服务实例用不同的HashCode加以区分,这样允许同名客户端的存在。
[ServiceContract(CallbackContract = typeof(ILigAgentCallback))]
public interface ILigAgent
{
[OperationContract]
LigStatus RegisterClient(string name);
[OperationContract]
LigStatus UnregisterClient(int clientID);
[OperationContract]
LigStatus Subscribe(int clientID);
[OperationContract]
LigStatus Unsubscribe(int clientID); }
public interface ILigAgentCallback
{
[OperationContract(IsOneWay = true)]
void OnNotifyMessage(string message);
[OperationContract(IsOneWay = true)]
void OnNotifyOnline(LigArgs args);
}
3.1.2 增加 数据契约类 LigArgs
说了半天。我们还没有正式应用数据契约。现在我们增加数据契约类用来在客户端与服务端进行通信时的数据传输。
此处LigArgs可以写成LigArgs : EventArgs,这样LigArgs可以变成EventHandler的事件参数岂不更好吗?
致于为什么不这样写,我们后面写ILigger时会回答这个问题。因为那时Lig已经完善。
[DataContract]
public class LigArgs
{
public LigArgs() { }
[DataMember]
public int ClientID { get; set; }
[DataMember]
public int HashID { get; set; }
[DataMember]
public bool ConnectStatus { get; set; }
[DataMember]
public string ClientName { get; set; }
[DataMember]
public string Message { get; set; }
}
3.2 服务实例管理 – 增加客户端实例上下文类
_________________________________________________________________________________
1) 我们在LigAgent类的内部增加一个内部类ClientContext,即客户端实例上下文类,这儿用来描述所注册客户端的信息。
2) 同时增加一个静态表dicClientsContext,用来保存注册客户端信息,其键名采用独立的HashCode。
Client信息就可以保存在Server端,Server端通过CallbackInstance给订阅客户端发送订阅消息。当客户端异常离线,Server将离线客户端信息从dicClientsContext中移除,移除的Client信息会由GC自动实现垃圾回收(当然此处最佳方案是采用弱引用(WeakReference)对ClientContext进行管理在性能上会更高效)。这样实现了Server对客户端资源的有效管理。
private static Dictionary<int, ClientContext> dicClientsContext = new Dictionary<int, ClientContext>();
#region InnerClasses
class ClientContext
{
internal ClientContext() { }
internal bool IsRegistered { get; set; }
internal bool IsSubscribed { get; set; }
internal int ClientID { get; set; }
internal int HashID { get; set; }
internal string ClientName { get; set; }
internal ILigAgentCallback CallbackInstance { get; set; }
internal OperationContext Context { get; set; }
}
#endregion
3.3 客户端 – 增加LigAgentCallback类
_________________________________________________________________________________
1) 在ConnectServer中将ChannelFactory换成DuplexChannelFactory。
2) 并注册LigAgentCallback内部的事件。我们通过LigAgentCallback内部的事件将回调消息发送给客户端。
this.callbackInstance = new LigAgentCallback();
this.SubscribedEvents();
//this.chnl = new ChannelFactory<ILigAgent>(SERVICENAME);
this.chnl = new DuplexChannelFactory<ILigAgent>(callbackInstance,SERVICENAME); private delegate void MessageHandler(string message);
private delegate void OnlineHandler(LigArgs args); #region InnerClasses
class LigAgentCallback : ILigAgentCallback
{
internal LigAgentCallback() { }
internal event MessageHandler msgReceived;
internal event OnlineHandler onlined;
public void OnNotifyMessage(string message)
{
if (this.msgReceived != null)
{
this.msgReceived(message);
}
}
public void OnNotifyOnline(LigArgs args)
{
if (this.onlined != null)
{
this.onlined(args);
}
}
internal void Release()
{ }
}
#endregion
图 3.3.1 在 LigManager内部订阅 LigAgentCallback内部事件
3.4 关于服务端监控 - LigAgent
_________________________________________________________________________________
原理:LigManager封装了ILigAgent接口资源。在LigAgent内部通过注册OperationContext.Channel属性的Closed事件实现对客户端的异常与正常离线监控。
context.Context.Channel.Closed += new EventHandler(OnShowOffline)
LigAgent内部用于注册LigClient客户端的内部函数AddClient
private LigStatus AddClient(string name,out int clientID)
{
clientID = -1;
int hash = this.GetHashCode();
if (string.IsNullOrEmpty(name)) return LigStatus.InvalidClient; if (dicClientsContext.ContainsKey(hash)) return LigStatus.ClientExisted; clientID = LigCore.ActiveID; ClientContext context = new ClientContext();
context.ClientID = clientID;
context.ClientName = name;
context.HashID = hash;
context.IsRegistered = true;
context.Context = OperationContext.Current;
context.CallbackInstance = OperationContext.Current.GetCallbackChannel<ILigAgentCallback>(); context.Context.Channel.Closed += new EventHandler(OnShowOffline); dicClientsContext.Add(hash, context);
Console.WriteLine(LigCore.LiggedTime + "Client with hashCode [" + hash.ToString() + "] is online!");
return LigStatus.Success;
}
3.5 双向通信 服务端监控 测试
_________________________________________________________________________________
测试。
启动LigServer,同时启动5个LigClient客户端。写完日志记客户端离线。观看消息变化。
1) Server已经成功的实现了对Client信息的监控。当客户端异常或正常离线,服务端对客户端实例资源进行移动操作
2) LigClient注册成功后,收到了来自LigServer的信息。。。
图 3.3.2 LigServer-LigClient双向通信 服务端监控
图 3.3.3 LigServer-LigClient双向通信 服务端监控
图 3.3.3 LigServer-LigClient双向通信 服务端监控 LigClient收来来自LigServer的信息
好了。到这里为止。Lig系统已经差不多满足我们的要求了。但还是不太完善,Lig系统还有上升的空间。我们前面说过,要优化LigClient使用的.等你看完
WCF 项目应用连载[4] - 自定义配置 扩展ServiceHost
WCF 项目应用连载[5] - 自定义配置 扩展ChannelFactory<T> 后,
WCF 项目应用连载[6] - 升级Lig服务 - 设计ILigger
将回答这一问题。
WCF 项目应用连载[6] - 升级Lig服务 - 设计ILigger以后。Lig工程将是一个比较完美的版本。
本节的源代码下载:
_________________________________________________________________________________
Litelog -WCF 项目应用连载[3] - 双向通信 并发 实例管理与服务端监控 源代码.rar
_________________________________________________________________________________
WCF 项目应用连载[4] - 自定义配置 扩展ServiceHost
参考引文:
[1] Artech.WCF全面解析[M].2012
[2] O'Reilly.WCF编程[M].2009
[3] Adnrew Trolesen.C#与.net3.5/4高级程序设计[M].2009/2013
WCF 项目应用连载[3] - 双向通信 实例管理与服务端监控的更多相关文章
- WCF 项目应用连载[2] - 创建Lig日志系统
WCF 项目应用连载[1] - 索引 - 轻量级的Log系统 - Lig Sample -序 现在我们创建一个Lig工程 - Litelog 2.1 创建Lig服务 _________________ ...
- WCF 项目应用连载[8] - 绑定、服务、行为 大数据传输与限流 - 下 (ServiceThrottlingAttribute)
因为ORM的原因,对Attribute编程有一种情节..所以这节的出现,完全是因为在WCF对自定义Attribute的一种应用. WCF 项目应用连载[7] - 绑定.服务.行为 大数据传输与限流 - ...
- 实例PK(Vue服务端渲染 VS Vue浏览器端渲染)
Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司 ...
- “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX
"快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...
- loadrunner 编写socket脚本实例(附服务端实现)
一.socket背景知识 这个咱就不废话了,网上一搜一大堆 二.本实例实现的功能 服务端接收客户端发送的字符串,并返回"5678succ"共8个字符 三.服务端实现(java代码) ...
- socket基础实例(一个服务端对应一个客户端情形)
服务端处理1个客户端的例子 运行结果: (1) while(accept+if(recv)) 情形 执行服务端进程: [root@localhost single_link]# ./server [s ...
- pm2 工具来管理 node 服务端
如下: nodeServer.js 'use strict'; const http = require('http'); const server = http.createServer(funct ...
- Netty实例-简单的服务端-client实现,凝视具体
书籍推荐: 实例代码 :http://download.csdn.net/detail/jiangtao_st ...
- 一: WCF的服务端与客户端在通信时有三种模式:请求响应模式、数据报模式和双工通讯模式。
说一下基本知识, 1.如果想要将当前接口作为wcf服务器,则一定要加上[ServiceContract] 契约 2.要想将方法作为wcf服务方法发布给外部调用,则一定要加上 [Operatio ...
随机推荐
- Cocos_Code_Ide学习(一):理解Cocos Lua Project下的frameworks的proj.win32
第一次写,不知道有没有用,有不对的地方,接受大家的批评.勿喷,谢谢. 1.首先,创建工程 ------------------------------------------------------- ...
- Jquery实现图片左右滚动(自动)
<!DOCTYPE HTML><html><head><title>基于jQuery的控制左右滚动效果_自动滚动版本</title>< ...
- printf 格式化最常用用法
printf 操作符的参数包括”格式字符串“及”要输出的数据列表". 格式字符串好像用来填空的模版,代表你想要的输出格式: printf "Hello,%s;your passwo ...
- Android单元测试初探——Instrumentation(转载)
学习Android有一段时间了,虽然前段时间对软件测试有了一些了解,不过接触android的单元测试却是头一次.这几天在物流大赛上也用了不少时间,所以对于android的单元测试没有太深入的研究,所以 ...
- 【Linux】常用命令
一.文件结构 /: 根目录 /bin: 系统所需要的那些命令位于此目录. /boot: Linux的内核及引导系统程序所需要的文件目录,GRUB或LILO系统引导管理器也 ...
- 【C语言】结构组成(函数、语句、注释)
C语言结构组成 一.相关基础知识 二.具体内容 C语言由函数.语句和注释三部分组成: )函数与主函数: 一个C语言源程序可以由一个或多个源文件组成,每个源文件可由一个或多个函数组成,一个源程序 ...
- Laravel框架——增删改查
增: //save返回true false $res = new member(); res->username = 'a'; $res->password = 'b'; dd($res- ...
- j
在Java程序或JSP程序中,其实有很多的代码段是可以重复使用的,比如对数据库的操作.用户的有效性检查及某些项特定功能的实现等.为了很好的解决这个问题,提高开发效率,Sun公司推出了JavaBean, ...
- OC 之 谓词
NSPredicate 分类: Objective-C iOS XCode Mac2012-10-26 17:26 10557人阅读 评论(1) 收藏 举报 简述:Cocoa框架中的NSPredica ...
- 【转】分享II→IV FPGA本人的几个版本电源模块设计的方案
很多人问我FPGA的电源怎么怎么着,当然也有人瞎忽悠乱设计,当然我的设计也不是很完美...这里把我当年第一次设计FPGA,到现在的电源方案,几个演变.分析的过程,给大家讲讲... (1)FPGA电源方 ...