一、从nuget里添加引用
1、添加SuperSocket引用
2、添加SuperSocket.Engine引用
二、添加RequestInfo类
public class DTRequestInfo : IRequestInfo
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="key">键值</param>
/// <param name="body">接收的数据体</param>
public DTRequestInfo(string key, byte[] body)
{
this.Key = key;
this.Body = body;
}
public string Key
{
get; set;
}
/// <summary>
/// 请求信息缓存
/// </summary>
public byte[] Body { get; set; }
/// <summary>
/// 设备ID
/// </summary>
public string DeviceID { get; set; }
}
三、添加AppSession类
public class DTSession : AppSession<DTSession, DTRequestInfo>
{
protected override void HandleException(Exception e)
{
base.HandleException(e);
}
protected override void OnSessionStarted()
{
base.OnSessionStarted();
}
protected override int GetMaxRequestLength()
{
return base.GetMaxRequestLength();
}
protected override void HandleUnknownRequest(DTRequestInfo requestInfo)
{
base.HandleUnknownRequest(requestInfo);
}
}
添加类:ReceiveFilterHelper
public abstract class ReceiveFilterHelper<TRequestInfo> : ReceiveFilterBase<TRequestInfo> where TRequestInfo : IRequestInfo
{
private SearchMarkState<byte> m_BeginSearchState;
private SearchMarkState<byte> m_EndSearchState;
private bool m_FoundBegin = false;
protected TRequestInfo NullRequestInfo = default(TRequestInfo);
/// <summary>
/// 初始化实例
/// </summary>
protected ReceiveFilterHelper()
{
}
/// <summary>
/// 过滤指定的会话
/// </summary>
/// <param name="readBuffer">数据缓存</param>
/// <param name="offset">数据起始位置</param>
/// <param name="length">缓存长度</param>
/// <param name="toBeCopied"></param>
/// <param name="rest"></param>
/// <returns></returns>
public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
{
rest = 0;
int searchEndMarkOffset;
int searchEndMarkLength;
//在此处做了处理,将接收到的第一个字符作为起始过滤标志,到结束。返回指定长度的数据。
byte[] startMark = new byte[] { readBuffer[offset] };
byte[] endMark = new byte[] { 0xff };
m_BeginSearchState = new SearchMarkState<byte>(startMark);
m_EndSearchState = new SearchMarkState<byte>(endMark);
//上一个开始标记长度
int prevMatched = 0;
int totalParsed = 0;
if (!m_FoundBegin)
{
prevMatched = m_BeginSearchState.Matched;
int pos = readBuffer.SearchMark(offset, length, m_BeginSearchState, out totalParsed);
if (pos < 0)
{
//不要缓存无效数据
if (prevMatched > 0 || (m_BeginSearchState.Matched > 0 && length != m_BeginSearchState.Matched))
{
State = FilterState.Error;
return NullRequestInfo;
}
return NullRequestInfo;
}
else //找到匹配的开始标记
{
//But not at the beginning
if (pos != offset)
{
State = FilterState.Error;
return NullRequestInfo;
}
}
//找到开始标记
m_FoundBegin = true;
searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length - prevMatched;
//This block only contain (part of)begin mark
if (offset + length <= searchEndMarkOffset)
{
AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
return NullRequestInfo;
}
searchEndMarkLength = offset + length - searchEndMarkOffset;
}
else//Already found begin mark
{
searchEndMarkOffset = offset;
searchEndMarkLength = length;
}
while (true)
{
var prevEndMarkMatched = m_EndSearchState.Matched;
var parsedLen = 0;
var endPos = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState, out parsedLen);
//没有找到结束标记
if (endPos < 0)
{
rest = 0;
if (prevMatched > 0)//还缓存先前匹配的开始标记
AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
AddArraySegment(readBuffer, offset, length, toBeCopied);
}
//totalParsed += parsedLen;
//rest = length - totalParsed;
totalParsed = 0;
byte[] commandData = new byte[BufferSegments.Count + prevMatched + totalParsed];
if (BufferSegments.Count > 0)
BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
if (prevMatched > 0)
{
Array.Copy(m_BeginSearchState.Mark, 0, commandData, BufferSegments.Count, prevMatched);
}
Array.Copy(readBuffer, offset, commandData, BufferSegments.Count + prevMatched, totalParsed);
var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);
Reset();
return requestInfo;
}
}
/// <summary>
/// Processes the matched request.
/// </summary>
/// <param name="readBuffer">The read buffer.</param>
/// <param name="offset">The offset.</param>
/// <param name="length">The length.</param>
/// <returns></returns>
protected abstract TRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length);
/// <summary>
/// Resets this instance.
/// </summary>
public override void Reset()
{
m_BeginSearchState.Matched = 0;
m_EndSearchState.Matched = 0;
m_FoundBegin = false;
base.Reset();
}
}
四、新建类 DTReceiveFilter
public class DTReceiveFilter : ReceiveFilterHelper<DTRequestInfo>
{
/// <summary>
/// 重写方法
/// </summary>
/// <param name="readBuffer">过滤之后的数据缓存</param>
/// <param name="offset">数据起始位置</param>
/// <param name="length">数据缓存长度</param>
/// <returns></returns>
protected override DTRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length)
{
//返回构造函数指定的数据格式
return new DTRequestInfo(Encoding.UTF8.GetString(readBuffer, offset, length), readBuffer);
}
}
添加 DTServer类:
public class DTServer : AppServer<DTSession, DTRequestInfo>
{
Timer requestTimer = null;
public DTServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, DTRequestInfo>())
{
//定时发送请求压力的报文
double sendInterval = 10;// double.Parse(ConfigurationManager.AppSettings["sendInterval"]);
requestTimer = new Timer(sendInterval);
requestTimer.Elapsed += RequestTimer_Elapsed;
requestTimer.Enabled = true;
requestTimer.Start();
}
private void RequestTimer_Elapsed(object sender, ElapsedEventArgs e)
{
//发送请求报文
var sessionList = GetAllSessions();
//Logger.Error(sessionList);
foreach (var session in sessionList)
{
Dictionary<string, string> routs = new Dictionary<string, string>();//wjx ConfigManager.GetAllConfig();
try
{
foreach (var item in routs)
{
if (item.Key.ToString().Contains("rout2_"))
{
string routeID = item.Key.ToString().Split('_')[1];
byte[] rout = HexConvertHelper.StringToHexByte(routeID);
byte[] address = HexConvertHelper.StringToHexByte(item.Value.ToString());
/// 合成报文
List<byte> data = new List<byte>();
data.Add(rout[0]);
data.Add(0x04);//读取数据
data.Add(address[0]);
data.Add(address[1]);
data.Add(address[2]);
data.Add(address[3]);
byte[] checkcode = HexConvertHelper.CRC16(data.ToArray());
data.Add(checkcode[1]);
data.Add(checkcode[0]);
/// 发送报文
//使用字节抽屉存储
// ArraySegment<byte> sendData = new ArraySegment<byte>(data.ToArray());
session.Send(data.ToArray(), 0, data.ToArray().Length);
// Console.WriteLine("发送数据:" + ConvertHelper.byteToHexStr(data.ToArray()));
}
}
}
catch (Exception ex)
{
//写入日志
/// Logger.Info(ex.Message);
}
}
}
protected override void OnNewSessionConnected(DTSession session)
{
base.OnNewSessionConnected(session);
//Logger.Error(session.SessionID);
}
protected override void ExecuteCommand(DTSession session, DTRequestInfo requestInfo)
{
base.ExecuteCommand(session, requestInfo);
}
protected override void OnStarted()
{
base.OnStarted();
}
protected override void OnStartup()
{
base.OnStartup();
}
protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
{
return base.Setup(rootConfig, config);
}
}