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实现.提供 ...
随机推荐
- python2.x与3.x差别
数字常量: 八进制 十六进制 二进制 2:0177 0o177 0x9ff 0b101010 3:0o177 0x9ff 0b101010 多种字符串: 2:一般字符串,Unicode字符串 3: ...
- web系统登陆页面增加验证码
传统登陆页面中包含两个输入项: • 用户名 • 密码有时为了防止机器人进行自动登陆操作,或者防止恶意用户进行用户信息扫描,需增加动态验证码功能.此时,登陆页面中包含了三个输入项: • 用户名 • 密码 ...
- selenium webdriver自动化测试
selenium家族介绍 Selenium IDE:Selenium IDE是嵌入到Firefox浏览器中的一个插件,实现简单的浏览器操作的录制与回放功能. Selenium ...
- 使用crypto模块实现md5加密功能(解决中文加密前后端不一致的问题)
正常情况下使用md5加密 var crypto = require('crypto'); var md5Sign = function (data) { var md5 = crypto.create ...
- 在Hyper-V中安装和配置Ubuntu网络
http://www.abcde.cn/knowledgebase/845/Hyper-VUbuntu.html (文中的nameserver要改成自己路由器的IP:我的是192.168.2.1.) ...
- h5移动端常见问题
meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 1 <meta name="viewport" content="width=device-w ...
- Python学习笔记 for windows
学习来源 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001374738136 ...
- php面试题
1.用PHP打印出前一天的时间格式是2006-5-10 22:21:21(2分) <?php date_default_timezone_set('Asia/shanghai'); echo d ...
- margin重叠现象与margin auto自适应居中
上下相邻的(算一种兄弟关系)普通元素,上下边距并非简单的相加,而是取其中最大的边距值:而浮动的盒子边距是相加的:父子div也会发生重叠,并不是bug: <style>#test1{ wid ...
- mac常用的命令
1.递归查找⽂文件内容: grep -r target_string absolute_path 2.移动所有⽂文件(包括隐藏⽂文件): mv * .[^.]* targetDir 3.⽂文件分割合并 ...