private void 执行自动重连() { var __检测间隔毫秒 = 5000; while (自动重连) { while (连接正常) { Thread.Sleep(__检测间隔毫秒); } if (Disposed) { break; } H日志输出.记录(称 + ": 开始自动重连"); On开始自动重连(); 开启(); if (!连接正常) { H日志输出.记录(称 + ": 自动重连失败"); Thread.Sleep(this.自动重连重试间隔秒数 * 1000); } else { H日志输出.记录(称 + ": 自动重连成功"); } } _已开启重连 = false; }
private bool 处理查询属性值(N会话参数 __会话参数) { var __请求 = __会话参数.负载 as M属性值查询请求; var __对象名称 = __请求.对象名称; var __属性名称 = __请求.属性名称; if (_所有对象.ContainsKey(__对象名称)) { var __对象 = _所有对象[__对象名称](); var __执行成功 = true; var __执行描述 = ""; var __返回值 = ""; try { __返回值 = __对象.计算属性(__属性名称); } catch (Exception ex) { H日志输出.记录(ex); __执行描述 = ex.Message; __执行成功 = false; } var 响应 = new M属性值查询结果 { 成功 = __执行成功, 描述 = __执行描述, 返回值 = __返回值 }; __会话参数.发送响应(响应); } return(true); }
public void 异步发送(byte[] __消息) { if (_连接 == null || _连接.Client == null || !_连接.Connected) { return; } try { _数据流.BeginWrite(__消息, 0, __消息.Length, new AsyncCallback(q => { try { _数据流.EndWrite(q); On发送成功(务器地址, __消息); H日志输出.记录(称 + string.Format(": 向 [{0}] 发", 务器地址), BitConverter.ToString(__消息)); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 向 [{0}] 发送失败, {1}", 务器地址, ex.Message)); } }), null); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 向 [{0}] 发送失败, {1}", 务器地址, ex.Message)); } }
public void 异步发送(IPEndPoint __客户端节点, byte[] __消息) { if (_所有客户端.ContainsKey(__客户端节点)) { var __客户端 = _所有客户端[__客户端节点]; try { __客户端.数据流.BeginWrite(__消息, 0, __消息.Length, new AsyncCallback(q => { try { __客户端.数据流.EndWrite(q); On发送成功(__客户端节点, __消息); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 向 [{0}] 发送失败, {1}", __客户端节点, ex.Message), BitConverter.ToString(__消息), TraceEventType.Information); } }), null); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 向 [{0}] 发送失败, {1}", __客户端节点, ex.Message), BitConverter.ToString(__消息), TraceEventType.Information); } } }
public void 关闭() { H日志输出.记录(称 + ": 关闭", null, TraceEventType.Information); lock (_客户端操作锁) { foreach (var kv in _所有客户端) { var __客户端 = kv.Value; __客户端.关闭 = true; if (__客户端.数据流 != null) { __客户端.数据流.Close(); } if (__客户端.连接 != null) { __客户端.连接.Close(); } } _所有客户端.Clear(); } if (_侦听器 != null) { _侦听器.Stop(); } }
private bool 处理执行方法(N会话参数 __会话参数) { var __请求 = __会话参数.负载 as M方法执行请求; var __对象名称 = __请求.对象名称; var __方法名称 = __请求.方法名称; var __参数 = __请求.实参列表; if (_所有对象.ContainsKey(__对象名称)) { var __对象 = _所有对象[__对象名称](); var __方法 = __对象.明细.方法列表.Find(q => q.称 == __方法名称); if (__方法 != null) { var __执行成功 = true; var __执行描述 = ""; var __返回值 = ""; try { __返回值 = __对象.执行方法(__方法名称, M实参.列表转字典(__参数), __会话参数.远端); } catch (Exception ex) { H日志输出.记录(ex); __执行描述 = ex.Message; __执行成功 = false; } var 响应 = new M方法执行结果 { 成功 = __执行成功, 描述 = __执行描述, 返回值 = __返回值 }; __会话参数.发送响应(响应); } } return(true); }
public void 异步接收数据(IAsyncResult ar) { var __绑定 = ar.AsyncState as Tuple <NetworkStream, byte[], M客户端>; var __数据流 = __绑定.Item1; var __缓存 = __绑定.Item2; var __客户端 = __绑定.Item3; try { int __实际接收长度 = __数据流.EndRead(ar); if (__实际接收长度 == 0) { if (_所有客户端.ContainsKey(__客户端.节点)) { 断开客户端(__客户端.节点, "接收长度为0"); } return; } var __实际接收字节 = new byte[__实际接收长度]; Buffer.BlockCopy(__缓存, 0, __实际接收字节, 0, __实际接收长度); H日志输出.记录(称 + string.Format(": 从 [{0}] 收", __客户端.节点), BitConverter.ToString(__实际接收字节)); _IN消息分割.接收数据(__客户端.节点, __实际接收字节); __数据流.BeginRead(__缓存, 0, 接收缓冲区大小, 异步接收数据, new Tuple <NetworkStream, byte[], M客户端>(__数据流, __缓存, __客户端)); } catch (Exception ex) { if (_所有客户端.ContainsKey(__客户端.节点)) { 断开客户端(__客户端.节点, ex.Message); } return; } }
private void 处理订阅事件(N会话参数 __会话参数) { var __订阅事件 = __会话参数.负载 as M订阅事件; var __对象名称 = __订阅事件.对象名称; var __事件名称 = __订阅事件.事件名称; var __远端 = __会话参数.远端; var __事件标识 = string.Format(_事件标识结构, __对象名称, __事件名称); lock (_lockobj) { if (!_所有事件订阅.ContainsKey(__事件标识)) { _所有事件订阅[__事件标识] = new List <IPEndPoint>(); } if (!_所有事件订阅[__事件标识].Contains(__远端)) { _所有事件订阅[__事件标识].Add(__远端); H日志输出.记录("接收[M订阅事件]", string.Format("[{0}] {1}.{2}", __远端, __对象名称, __事件名称), TraceEventType.Information); } } //下列代码有同步问题 //var __订阅地址列表 = _所有事件订阅.GetOrAdd(__事件标识, q => new List<IPEndPoint>()); //if (!__订阅地址列表.Contains(__远端)) //{ // __订阅地址列表.Add(__远端); // H日志输出.记录("接收[M订阅事件]", string.Format("[{0}] {1}.{2}", __远端, __对象名称, __事件名称), TraceEventType.Information); //} }
private void 异步接收数据(IAsyncResult ar) { IPEndPoint __地址 = null; byte[] __接收字节 = null; try { try { __接收字节 = _连接.EndReceive(ar, ref __地址); } catch (Exception) { } if (__接收字节 == null || __接收字节.Length == 0) { return; } H日志输出.记录(string.Format("{0}: 从 [{1}] 收", 称, __地址), BitConverter.ToString(__接收字节)); On收到消息(__地址, __接收字节); _连接.BeginReceive(异步接收数据, null); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 从 [{0}] 接收异常", __地址), ex.Message, TraceEventType.Warning); } }
public M每通道线程(IPEndPoint __节点, string __通道, Action <object> __处理数据) { _节点 = __节点; _通道 = __通道; new System.Threading.Thread(() => { while (!_关闭) { M事项 __事项; if (_队列.TryDequeue(out __事项)) { var __延迟 = Environment.TickCount - __事项.接收时间; if (__延迟 > 500) { H日志输出.记录(string.Format("处理 [{0}][{1}] 的 {2} 延迟 {3} 毫秒;", _节点, _通道, __事项.数据, __延迟)); } __处理数据(__事项.数据); System.Threading.Thread.Sleep(0); } else { System.Threading.Thread.Sleep(100); } } }) { IsBackground = true }.Start(); }
public override void 处理接收(IPEndPoint __远端, IN事务报文 __报文, IN上下文 __上下文) { var __二进制报文 = __报文 as P二进制报文; if (__二进制报文.对象 is M注册请求) { H日志输出.记录("服务器: 客户端请求注册", __远端.ToString()); //验证账号 H日志输出.记录("服务器: 验证账号"); //验证成功 H日志输出.记录("服务器: 验证通过"); this.发送响应(__远端, new P二进制报文(new M注册成功 { 角色 = 0, 注册标识 = 1 })); this.关闭请求(); __上下文.注册标识[__远端] = 1; //心跳 H日志输出.记录("服务器: 开启心跳任务"); Task.Factory.StartNew(() => { Thread.Sleep(2000); while (true) { this.发送通知(__远端, new P二进制报文(new M心跳())); Thread.Sleep(5000); } }); } }
public M每节点线程(IPEndPoint __节点, Action <object> __处理数据) { _节点 = __节点; new System.Threading.Thread(() => { while (!_关闭) { var __所有通道 = _队列字典.Keys.ToList(); __所有通道.ForEach(__通道 => { ConcurrentQueue <M事项> __队列; if (!_队列字典.TryGetValue(__通道, out __队列)) { return; } M事项 __事项; if (__队列.TryDequeue(out __事项)) { var __延迟 = Environment.TickCount - __事项.接收时间; if (__延迟 > 500) { H日志输出.记录(string.Format("处理 [{0}][{1}] 的 {2} 延迟 {3} 毫秒;", _节点, __通道, __事项.数据, __延迟)); } __处理数据(__事项.数据); } }); System.Threading.Thread.Sleep(10); } }) { IsBackground = true }.Start(); }
public void 触发事件(string __对象名称, string __事件名称, Dictionary <string, string> __参数列表 = null, List <IPEndPoint> __地址列表 = null) { var __事件标识 = string.Format(_事件标识结构, __对象名称, __事件名称); List <IPEndPoint> __订阅地址列表; if (!_所有事件订阅.TryGetValue(__事件标识, out __订阅地址列表)) { return; } if (__地址列表 == null) { __地址列表 = new List <IPEndPoint>(__订阅地址列表); } __地址列表.ForEach(__远端 => { if (客户端列表.Contains(__远端)) { _IN上下文.发送通知(__远端, new M接收事件 { 对象名称 = __对象名称, 实参列表 = M实参.字典转列表(__参数列表), 事件名称 = __事件名称, }); H日志输出.记录("触发[M订阅事件]", string.Format("{3}-{4}[{0}] {1}.{2}", __远端, __对象名称, __事件名称, 客户端列表.Count, __地址列表.Count), TraceEventType.Information); } else { _所有事件订阅[__事件标识].Remove(__远端); } }); }
public void 注销请求(int 凭据) { H日志输出.记录(string.Format("{1}: 关 {0}", 凭据, 称)); List <IN处理报文> temp; _所有请求.TryRemove(凭据, out temp); }
public void 异步接收数据(IAsyncResult ar) { var __绑定 = ar.AsyncState as Tuple <NetworkStream, byte[]>; var __数据流 = __绑定.Item1; var __缓存 = __绑定.Item2; try { int __实际接收长度 = __数据流.EndRead(ar); if (__实际接收长度 == 0) { 断开(); return; } var __实际接收字节 = new byte[__实际接收长度]; Buffer.BlockCopy(__缓存, 0, __实际接收字节, 0, __实际接收长度); H日志输出.记录(称 + string.Format(": 从 [{0}] 收", 务器地址), BitConverter.ToString(__实际接收字节)); _IN消息分割.接收数据(务器地址, __实际接收字节); __数据流.BeginRead(__缓存, 0, 接收缓冲区大小, 异步接收数据, new Tuple <NetworkStream, byte[]>(_数据流, __缓存)); } catch (Exception ex) { if (连接正常) { H日志输出.记录(称 + string.Format(": 从 [{0}] 接收异常", 务器地址), ex.Message, TraceEventType.Warning); 断开(); } } }
public void 添加事项 <T>(string __队列标识, T __数据, Action <T> __处理数据, H队列监控 __监控 = null) { if (_已关闭) { return; } //Debug.WriteLine("{0} 添加事项 {1}", DateTime.Now.ToString("HH:mm:ss.fff"), __数据); var __接收时间 = Environment.TickCount; var __队列 = _队列字典.GetOrAdd(__队列标识, k => new ConcurrentQueue <Action>()); __队列.Enqueue(() => { if (!_取消标志.IsCancellationRequested) { try { //Debug.WriteLine("{0} 执行事项 {1}", DateTime.Now.ToString("HH:mm:ss.fff"), __数据); if (__监控 == null) { __处理数据(__数据); } else { __监控.监控下执行(_名称, __数据, __接收时间, __处理数据); } } catch (Exception ex) { H日志输出.记录(ex, _名称); } } }); Interlocked.Increment(ref _待处理数量); }
public void 清空(IPEndPoint __节点) { H日志输出.记录("清空解码缓存: " + __节点); if (_所有数据流.ContainsKey(__节点)) { this._所有数据流.Remove(__节点); } }
public void 连接(IPEndPoint __设备端口) { H日志输出.记录("创建客户端"); __IN网络节点 = FN网络传输工厂.创建TCP客户端(__设备端口, new IPEndPoint(IPAddress.Any, 5555), P报文.消息头长度, P报文.解码消息长度); __IN网络节点.称 = "客户端"; //__客户端.自动重连 = true; _IN上下文 = new N上下文(); __IN网络节点.收到消息 += (__远端地址, __消息) => { var __报文 = H报文注册.解码(__消息); if (__报文 == null) { return; } _IN上下文.收到报文(__远端地址, __报文); }; __IN网络节点.已断开 += () => H日志输出.记录("客户端: 与服务器断开", string.Empty); __IN网络节点.已连接 += () => { 连接正常 = true; On已连接(); On收到了通知(new M通知 { 对象 = "系统", 概要 = "欢迎进入", 详细 = "", 重要性 = "普通" }); Task.Factory.StartNew(() => { byte[] __心跳 = new P心跳().编码(); while (__IN网络节点.连接正常) { __IN网络节点.异步发送(__心跳); Thread.Sleep(10000); } }); Task.Factory.StartNew(() => { _最后心跳时间 = DateTime.Now; while (__IN网络节点.连接正常) { if (_最后心跳时间.AddMilliseconds(_心跳频率 * 5) < DateTime.Now) { On已断开(false); } Thread.Sleep(_心跳频率); } }); }; H日志输出.记录("配置客户端上下文"); _IN上下文.设置发送方法((__节点, __消息) => __IN网络节点.步发送(__消息)); _IN上下文.订阅报文(typeof(P心跳), () => this); _IN上下文.订阅报文(typeof(P通知), () => this); __IN网络节点.开启(); }
protected override object 解码(string __功能码, byte[] __负载数据) { var __字符串 = _编码.GetString(__负载数据); H日志输出.记录(string.Format("解码报文 [{0}]", __功能码), __字符串); var __类型 = Type.GetType(__功能码, true); return(HJson编解码.解码(__类型, __字符串)); }
public override void 处理接收(IPEndPoint __远端, IN事务报文 __报文, IN上下文 __上下文) { var __二进制报文 = __报文 as P二进制报文; if (__二进制报文.对象 is M心跳) { H日志输出.记录("服务器: 收到心跳", __远端.ToString()); } }
protected override object 解码(Int16 __功能码, byte[] __负载数据) { var __字符串 = _编码.GetString(__负载数据); H日志输出.记录(string.Format("解码报文 [{0}]", __功能码.ToString("X4")), __字符串); var __类型 = 报文字典[__功能码]; return(HJson编解码.解码(__类型, __字符串)); }
public void 开启() { var __编解码器 = new B编解码器(H报文注册.报文字典, null, FT通用访问工厂.文本编码) { 编码拦截 = H报文注册.拦截发送报文, 解码拦截 = H报文注册.拦截接收报文 }; 客户端列表 = new List <IPEndPoint>(); _IN网络节点 = FN网络传输工厂.创建TCP服务器(new IPEndPoint(IPAddress.Any, 端口), __编解码器.消息头长度, __编解码器.解码消息长度); _IN网络节点.称 = "服务器"; _IN上下文 = new N上下文(__编解码器, _IN网络节点.称); _IN网络节点.收到消息 += (__远端地址, __消息) => _IN上下文.收到报文(__远端地址, __消息); _IN网络节点.客户端已连接 += q => { if (!客户端列表.Contains(q)) { 客户端列表.Add(q); } On客户端已连接(q); }; _IN网络节点.客户端已断开 += q => { if (客户端列表.Contains(q)) { 客户端列表.Remove(q); } On客户端已断开(q); _IN上下文.注销节点(q); }; _IN上下文.设置发送方法(_IN网络节点.步发送); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M对象列表查询请求)), () => new N被动会话(new Func <N会话参数, bool>(处理查询对象列表))); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M对象明细查询请求)), () => new N被动会话(new Func <N会话参数, bool>(处理查询对象明细))); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M方法执行请求)), () => new N被动会话(new Func <N会话参数, bool>((处理执行方法)))); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M订阅事件)), () => new N被动会话(new Action <N会话参数>((处理订阅事件)))); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M注销事件)), () => new N被动会话(new Action <N会话参数>((处理取消订阅事件)))); _IN上下文.订阅报文(H报文注册.查询功能码(typeof(M属性值查询请求)), () => new N被动会话(new Func <N会话参数, bool>((处理查询属性值)))); _IN网络节点.最大消息长度 = 10000000; _IN网络节点.开启(); try { if (WebApi端口 == 0) { WebApi端口 = 端口 + 1; } _BWebApi = new BWebApi(WebApi端口, () => _所有对象); _BWebApi.开启(); } catch (Exception ex) { H日志输出.记录("通用访问WebApi开启失败: " + ex.Message); } }
void 处理报文(object __参数) { var __数据 = __参数 as M数据; if (__数据 == null) { return; } //H日志输出.记录(string.Format("{0}: 处理 [{1}] 的报文", 名称, __数据.来源), string.Format("事务:{0}-{1}; 功能码:{2}; 负载:{3};", __数据.事务.发方事务, __数据.事务.收方事务, __数据.事务.功能码, __数据.负载)); var __来源 = __数据.来源; var __事务 = __数据.事务; var __负载 = __数据.负载; //通知或请求开始,转发报文后获得会话处理对象,加入到当前会话中 if (__事务.收方事务 == 0) { var __请求型会话 = __事务.发方事务 != 0; var __本地业务标识 = 0; if (__请求型会话) { __本地业务标识 = 生成业务标识(); __事务.收方事务 = __本地业务标识; } var __报文处理列表 = _报文处理.触发返回(__事务.功能码); foreach (var __处理方法 in __报文处理列表) { var __处理会话 = (IN处理报文)__处理方法; __处理会话.本地凭据 = __本地业务标识; __处理会话.远端凭据 = __事务.发方事务; __处理会话.文 = this; if (__请求型会话) { H日志输出.记录(string.Format("{1}: 开 {0}", __本地业务标识, 称)); if (!_所有请求.ContainsKey(__本地业务标识)) { _所有请求[__本地业务标识] = new List <IN处理报文>(); } _所有请求[__本地业务标识].Add(__处理会话); } __处理会话.处理接收(__来源, __事务, __负载, this); } return; } //请求过程中,匹配到当前会话中的处理对象,处理报文 List <IN处理报文> __会话列表; if (_所有请求.TryGetValue(__事务.收方事务, out __会话列表)) { foreach (var __处理会话 in __会话列表) { __处理会话.远端凭据 = __事务.发方事务; __处理会话.处理接收(__来源, __事务, __负载, this); } } }
public int 注册请求(IN处理报文 处理请求) { var __本地业务标识 = 生成业务标识(); _所有请求[__本地业务标识] = new List <IN处理报文> { 处理请求 }; H日志输出.记录(string.Format("{1}: 开 {0}", __本地业务标识, 称)); return(__本地业务标识); }
public void 开启() { if (称 == null) { 称 = string.Format("服务器 [{0}]", 本机地址); } _IN消息分割.最大消息长度 = this.最大消息长度; 开启时间 = DateTime.Now; H日志输出.记录(string.Format("{0}: 监听 {1}", 称, this.本机地址), null, TraceEventType.Information); _侦听器 = new TcpListener(this.本机地址); _侦听器.Start(); _侦听器.BeginAcceptTcpClient(异步侦听, _侦听器); }
public void 添加事项 <T>(T __数据, Action <T> __处理数据, H队列监控 __监控 = null) { //Debug.WriteLine("{0} 添加事项 {1}", DateTime.Now.ToString("HH:mm:ss.fff"), __数据); if (_已关闭) { return; } var __接收时间 = Environment.TickCount; Action __任务项 = () => { try { //Debug.WriteLine("{0} 执行事项 {1}", DateTime.Now.ToString("HH:mm:ss.fff"), __数据); if (__监控 == null) { __处理数据(__数据); } else { __监控.监控下执行(_名称, __数据, __接收时间, __处理数据); } } catch (Exception ex) { H日志输出.记录(ex, _名称); } }; _队列.Enqueue(__任务项); if (_队列.Count == 1) { Task.Factory.StartNew(() => { Action __事项; while (_队列.TryDequeue(out __事项)) { if (_取消标志.IsCancellationRequested) { break; } __事项(); } if (_已关闭) { _同步信号.Set(); return; } }, _取消标志.Token); } }
public void 异步发送(IPEndPoint __远端地址, byte[] __消息) { _连接.BeginSend(__消息, __消息.Length, new AsyncCallback(q => { try { _连接.EndSend(q); On发送成功(__远端地址, __消息); H日志输出.记录(称 + string.Format(": 向 [{0}] 发", __远端地址), BitConverter.ToString(__消息)); } catch (Exception ex) { H日志输出.记录(称 + string.Format(": 向 [{0}] 发送失败, {1}", __远端地址, ex.Message)); } }), null); }
private bool 处理查询对象明细(N会话参数 __会话参数) { var __对象名称 = (__会话参数.负载 as M对象明细查询请求).对象名称; if (_所有对象.ContainsKey(__对象名称)) { var __对象 = _所有对象[__对象名称](); __会话参数.发送响应(__对象.明细); } else { H日志输出.记录("无此对象: " + __对象名称); } return(true); }
private void 分析数据流(IPEndPoint __节点, List <byte> __数据流) { if (__数据流.Count == 0) { return; } if (__数据流.Count < this._消息头长度) { H日志输出.记录(string.Format("缓存的字节流长度不足报文头:{0}", BitConverter.ToString(__数据流.ToArray()))); return; } //验证报文长度 var __报文头 = new byte[_消息头长度]; for (int j = 0; j < _消息头长度; j++) { __报文头[j] = __数据流[j]; } var __报文内容长度 = _解码消息内容长度(__报文头); if (__报文内容长度 > 最大消息长度 || __报文内容长度 < 0) { //截取掉 H日志输出.记录(string.Format("报文内容长度 {0} 非法,清空缓存的字节流:{1}", __报文内容长度, BitConverter.ToString(__数据流.ToArray()))); __数据流.Clear(); return; } //验证流长度 if (__报文内容长度 > __数据流.Count - this._消息头长度) { //等待 H日志输出.记录("报文内容未接收完整,等待后续数据"); return; } //解码实际报文 var __报文总长度 = this._消息头长度 + __报文内容长度; var __报文字节 = __数据流.GetRange(0, __报文总长度).ToArray(); __数据流.RemoveRange(0, __报文总长度); On已分割消息(__节点, __报文字节); //循环解码,处理粘包 分析数据流(__节点, __数据流); }
protected void On已分割消息(IPEndPoint __节点, byte[] __消息) { try { var handler = 已分割消息; if (handler != null) { handler(__节点, __消息); } } catch (Exception e) { H日志输出.记录(string.Format("处理字节流出错: {0}", BitConverter.ToString(__消息))); H日志输出.记录(e); } }