MessageReceiver
class MessageReceiver
{
private RelayEngine<MessageCollection> _MessageRelayEngine;
private string _Hostname;
private int _MessageDispatchServerPort;
private string _SessionId;
private TcpClient _Client;
private bool _Stopped = false;
private Thread _Worker = null;
private ulong _LastMessageSequence = 0; internal MessageReceiver(RelayEngine<MessageCollection> messageRelayEngine)
{
this._MessageRelayEngine = messageRelayEngine;
} internal void Start(string hostname, int messageDispatchServerPort, string sessionId)
{
this.Stop(); this._Stopped = false; this._Hostname = hostname;
this._MessageDispatchServerPort = messageDispatchServerPort;
this._SessionId = sessionId; this._Worker = new Thread(ConnectServerAndReceiveMessage);
this._Worker.IsBackground = true;
this._Worker.Start();
} internal void SetSessionId(string newSessionId)
{
this._SessionId = newSessionId;
} private void ConnectServerAndReceiveMessage(object state)
{
byte[] header = new byte[4];
int defaultBufferLen = 1024 * 64;
byte[] defaultBuffer = new byte[defaultBufferLen]; while (!this._Stopped)
{
this._Client = null;
NetworkStream stream = null; try
{
Logger.TraceEvent(TraceEventType.Information, "MessageReceiver.ConnectServerAndReceiveMessage to connect {0}:{1}", _Hostname, _MessageDispatchServerPort); this._Client = new TcpClient();
this._Client.Connect(_Hostname, _MessageDispatchServerPort);
stream = this._Client.GetStream(); byte[] sessionData = ASCIIEncoding.ASCII.GetBytes(this._SessionId);
byte[] sessionDataLen = new byte[2] { (byte)(sessionData.Length >> 8), (byte)sessionData.Length };
stream.Write(sessionDataLen, 0, sessionDataLen.Length);
stream.Write(sessionData, 0, sessionData.Length);
}
catch (Exception ex)
{
Logger.TraceEvent(TraceEventType.Error, "MessageReceiver.ConnectServerAndReceiveMessage error:\r\n{0}", ex);
this.CloseConectionSilently();
continue;
} while (true)
{
Array.Clear(header, 0, header.Length);
if (!this.ReadAll(stream, header))
{
Logger.TraceEvent(TraceEventType.Information, "MessageReceiver.ConnectServerAndReceiveMessage read header data failed");
this.CloseConectionSilently();
break;//reconnect
} int dataLength = ((int)header[0] << 24) + ((int)header[1] << 16) + ((int)header[2] << 8) + header[3];
byte[] buffer = dataLength <= defaultBufferLen ? defaultBuffer : new byte[dataLength]; if (!this.ReadAll(stream, buffer, dataLength))
{
Logger.TraceEvent(TraceEventType.Information, "MessageReceiver.ConnectServerAndReceiveMessage read message data failed");
this.CloseConectionSilently();
break;//reconnect
} try
{
MessageCollection message = CompressHelper.FromByteArray<MessageCollection>(buffer, dataLength);
if (message.Sequence != this._LastMessageSequence)
{
Logger.TraceEvent(TraceEventType.Warning, "MessageReceiver.ConnectServerAndReceiveMessage got message with worng sequence {0}, excepted sequece is {1}",
message.Sequence, this._LastMessageSequence);
}
this._LastMessageSequence++; this._MessageRelayEngine.AddItem(message);
ConsoleClient.Instance.RefreshLastMsgTime();
}
catch (Exception ex)
{
Logger.TraceEvent(TraceEventType.Error, "MessageReceiver.ConnectServerAndReceiveMessage add message to engine error:\r\n{0}", ex);
}
}
}
} private void CloseConectionSilently()
{
try
{
if (this._Client != null)
{
this._Client.Close();
this._Client = null;
}
}
catch (Exception ex)
{
Logger.TraceEvent(TraceEventType.Error, "MessageReceiver CloseConectionSilently error:\r\n{0}", ex);
}
} private bool ReadAll(NetworkStream stream, byte[] buffer, int? dataLength = null)
{
try
{
int offset = 0;
int len = dataLength.HasValue ? dataLength.Value : buffer.Length; while (len > 0)
{
if (!stream.DataAvailable)
{
Thread.Sleep(100);
continue;
}
int readLength = stream.Read(buffer, offset, len);
if (readLength == 0)
{
return false;
}
else
{
offset += readLength;
len -= offset;
}
}
return true;
}
catch (Exception ex)
{
Logger.TraceEvent(TraceEventType.Warning, "MessageReceiver.ReadAll error:\r\n{0}", ex.ToString());
return false;
}
} internal void Stop()
{
this._Stopped = true;
this._LastMessageSequence = 0;
this.CloseConectionSilently();
if (this._Worker != null)
{
this._Worker.Join(1000);
this._Worker = null;
}
}
}
MessageReceiver的更多相关文章
- axis2+spring集成
转载自:http://www.cnblogs.com/linjiqin/archive/2011/07/05/2098316.html 1.新建一个web project项目,最终工程目录如下: 注意 ...
- 使用poco 的NetSSL_OpenSSL 搭建https 服务端,使用C++客户端,java 客户端访问,python访问(python还没找到带证书访问的代码.)
V20161028 由于项目原因,需要用到https去做一些事情. 这儿做了一些相应的研究. 这个https 用起来也是折腾人,还是研究了一周多+之前的一些积累. 目录 1,java client 通 ...
- webservice 小小例子
Web Service的主要目标是跨平台的可互操作性.为了实现这一目标,Web Service 完全基于XML(可扩展标记语言).XSD(XML Schema)等独立于平台.独立于软件供应商的标准,是 ...
- Spring Rabbitmq HelloWorld实例
之前的博客和大家分享了Rabbitmq的基本框架,及其工作原理,网址为 < http://www.cnblogs.com/jun-ma/p/4840869.html >.今天呢,想和大家一 ...
- 深入浅出Alljoyn——实例分析之远程调用(Method)篇
深入浅出就是很深入的学习了很久,还是只学了毛皮,呵呵! 服务端完整代码: #include <qcc/platform.h> #include <assert.h> #incl ...
- Java借助axis2发布WebService
Webservice: 1.Xml: 2.WSDL: Web service描述语言(WSDL)就是这样一个基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web service及其函数.参 ...
- ActiveMQ 即时通讯服务 浅析
一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provi ...
- webservice发布服务:AXIS2及客户端调用
1.Axis2: 到官网下载axis2的压缩包. 解压后: 1.将lib文件下的jar包复制到项目中 2.在web-inf下创建services->META-INF->services.x ...
- ActiveMQ开发与简介
1.概述与介绍 ActiveMQ是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMSProvider实现.提供 ...
随机推荐
- windows计划任务+批处理文件实现oracle数据库的定时备份与恢复
1. 备份: PS:2014-1-15 如果导出的dmp数据文件不大的话,就直接每天导出好了,不要只保存七天的数据.然后顶起通过winrar对文件进行打包,我发现dmp文件的压缩包还是很高的. 那么 ...
- “maven编码gbk的不可映射字符”解决办法
一.问题描述 Eclipse中使用Maven编译项目源代码时,如下的错误 java源代码在Eclipse中显示是没有任何错误的,可是执行"maven install"命令编译项目时 ...
- Mybatis缓存处理机制
一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ...
- 准备上线,切换到master分支,报错
切换到master分支,准备上线,把上次上线sourceTree保存的修改拉出来: 运行,报错了: stackOverflow一搜说要删除旧的: 我show in finder 把他删了,然后双击安装 ...
- visual studio code 里调试运行 Python代码
最近对微软的visual studio code 挺感兴趣的,微软的跨平台开发工具.轻量简洁. 版本迭代的也挺快的,截止16年8月2日已经1.3.1版本了,功能也愈加完善.(16年12月18日 已经, ...
- 理解AX InventTrans的几种状态
接触AX一段时间后,发现InventTrans表非常重要.它可以说是物流模块的核心,开发BI报表的话必须依赖此报表. 先来看官方释义: InventTrans表包含了库存交易的信息.当销售/采购订 ...
- oracle查询某个时间点的数据
1. select * from emps as of timestamp to_Date('2015-12-11 14:00:00','yyyy-mm-dd hh24:mi:ss'),SQL语句是查 ...
- iOS推送遇到的问题
1. 推送证书过期. 同事说iOS客户端不能推送消息,发现推送证书过期了,苹果的推送证书有效期是一年,推送证书过期后就不能使用推送服务了.解决办法:重新请求推送证书,导出p12文件,传给后台服务器就可 ...
- 鼠绘漫画 for wp8.1
技术规格总结: 这个APP 总体上是下载图片的一个APP 所以对图片的查看&控制上需要一定功力,至少有一个稳定的缩小,放大的图片控件. 搭载WP系统的手机,内存上大部分不是很大,所以内存的控制 ...
- 关于iOS和android自定义包的名字
自定义包名的使用,android的包名和ios的包名都是你的自定义包名!如下以新浪微博SDK自定义包名示例:(官方没的,自己踩过坑,方便后来人吧) 相关技术文档:http://www.apicloud ...