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的更多相关文章

  1. axis2+spring集成

    转载自:http://www.cnblogs.com/linjiqin/archive/2011/07/05/2098316.html 1.新建一个web project项目,最终工程目录如下: 注意 ...

  2. 使用poco 的NetSSL_OpenSSL 搭建https 服务端,使用C++客户端,java 客户端访问,python访问(python还没找到带证书访问的代码.)

    V20161028 由于项目原因,需要用到https去做一些事情. 这儿做了一些相应的研究. 这个https 用起来也是折腾人,还是研究了一周多+之前的一些积累. 目录 1,java client 通 ...

  3. webservice 小小例子

    Web Service的主要目标是跨平台的可互操作性.为了实现这一目标,Web Service 完全基于XML(可扩展标记语言).XSD(XML Schema)等独立于平台.独立于软件供应商的标准,是 ...

  4. Spring Rabbitmq HelloWorld实例

    之前的博客和大家分享了Rabbitmq的基本框架,及其工作原理,网址为 < http://www.cnblogs.com/jun-ma/p/4840869.html >.今天呢,想和大家一 ...

  5. 深入浅出Alljoyn——实例分析之远程调用(Method)篇

    深入浅出就是很深入的学习了很久,还是只学了毛皮,呵呵! 服务端完整代码: #include <qcc/platform.h> #include <assert.h> #incl ...

  6. Java借助axis2发布WebService

    Webservice: 1.Xml: 2.WSDL: Web service描述语言(WSDL)就是这样一个基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web service及其函数.参 ...

  7. ActiveMQ 即时通讯服务 浅析

      一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provi ...

  8. webservice发布服务:AXIS2及客户端调用

    1.Axis2: 到官网下载axis2的压缩包. 解压后: 1.将lib文件下的jar包复制到项目中 2.在web-inf下创建services->META-INF->services.x ...

  9. ActiveMQ开发与简介

    1.概述与介绍 ActiveMQ是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMSProvider实现.提供 ...

随机推荐

  1. jQuery系列:五个模块总结

    Query插件,以备并希望在前端方面有所长进.请批评指正. 一,类型判断全解 JQuery判断类型扩展方法:$.type() /*type: function( obj ) { if ( obj == ...

  2. 微信 {"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}

    {"errcode":,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]&q ...

  3. Thinking in Java——笔记(15)

    Generics The term "generic" means "pertaining or appropriate to large groups of class ...

  4. JBoss QuickStart之Helloworld

    下载Jboss, quickstart, 按照quickstart说明, mvn clean install. 由于ssl handshake问题(应该是网络连接不稳定), 写了一个脚本不停地尝试bu ...

  5. vert.x学习(二),使用Router来定义用户访问路径

    这里需要用到vertx-web依赖了,依然是在pom.xml里面导入 <?xml version="1.0" encoding="UTF-8"?> ...

  6. Reveal - UI 分析工具

    一.安装和简介 a) download url b) Reveal 使用的方法有两种: Static Library Intefration, Dynamic Library Intefration. ...

  7. flex 弹性布局

         采用 flex 布局的元素称为容器,其所有子元素称为项目.常用: 容器上可以设置六个属性:flex-direction.flex-wrap.flex-flow.justify-content ...

  8. 启动eclipse时:java is started but returned code 13

    此问题是eclipse位数和java位数不匹配造成的 我的是win10 64位的eclipse + 32位的java造成的问题 查看eclipse位数:用记事本打开eclipse根目录下的eclips ...

  9. 上传图片插件鼠标手cursor:pointer;不生效

    问题: 只在谷歌里失效; 解决: font-size:0; 参考: http://jingyan.baidu.com/article/48b558e32fabb67f38c09a81.html htt ...

  10. 尝试自己翻译了FreeCodeCamp的文章,技术方面多认识了几种技术,文章标题:Transparency in Action Free Code Camp is Now Open Source

    这是FreeCodeCamp其中一篇文章,趁着学习英文的时间,翻译这篇文章,其中讲到作者创建FCC过程,本文属于原创,第一次翻译,翻译还有诸多不足之处,请大家包含. 原文地址:https://medi ...