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实现.提供 ...
随机推荐
- javaScript条件控制语句
当某段代码的执行,需要首先满足某些条件时,我们就需要用到条件控制语句.判断条件是否满足,满足条件才去执行某些代码. 如判断数组中值等于条件值时,将这个值从数组中删除 a.switch <scri ...
- __DATE__ 与 __TIME__转换为标准格式时间字符串的方法
// Example of __DATE__ string: "Jul 27 2012"// 01234567890 #define BUILD_YEAR_CH0 (__DATE_ ...
- swfit-计时器
import UIKit class FourVC: UIViewController { var label:UILabel = UILabel() var index : Int = var ti ...
- FTP上传文件提示550错误原因分析。
今天测试FTP上传文件功能,同样的代码从自己的Demo移到正式的代码中,不能实现功能,并报 Stream rs = ftp.GetRequestStream()提示远程服务器返回错误: (550) 文 ...
- undefined reference to `libiconv_open 无法编译PHP
解决方法:#wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz#tar -zxvf libiconv-1.13.1.tar. ...
- 函数式中的 currying
currying 是函数式语言中经常遇到的一个概念,翻译成 柯里化,不是库里化. currying 指的是将接收多个参数的函数变换成接收一个单一参数,并且返回接收余下的参数而且返回结果的新函数的技术. ...
- Log4J的入门简介学习【转】
原文:http://blog.csdn.net/lengyuhong/article/details/5832799 简介: Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以 ...
- 小技巧,关于OC打印指针地址和arc下的retaincount
CFGetRetainCount((__bridge CFTypeRef)self : 打印retainCount 打印指针的地址(不是指针指向对象的地址):NSLog(@"aStr指针内 ...
- java中分页效果的实现代码
首先是将分页所需的一些个资源 ,抽象出一个javabean对象-PageBean: 先把需要分页的数据或是记录都查询出来 存入一个集合类里如List或是Vector, 然后利用其sublist(int ...
- android内存分析:heap Snapshot的使用
网上有很多讲解关于android studio中memory工具的使用,接下来我来说一段在项目中发生的实例:大家可以根据我的这个方法来分析自己项目中的问题 首先我们要通过手动先触发GC操作,点击mem ...