添加断线,心跳和鉴权

master
CZ 8 months ago
commit a01fa6028a

Binary file not shown.

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace HybirdFrameworkServices.Charger.BatCharging.Manager
{
/// <summary>
/// 管理充电机信息
/// </summary>
public class ChargerEqmManager
{
public Channel<byte[]> messageQueue;
/// <summary>
/// 充电机通讯连接线程
/// </summary>
public void ChargerNetConnectThread()
{
Thread chrgConnectThread = new Thread(ChargerNetConnectFunc);
chrgConnectThread.IsBackground = true;
chrgConnectThread.Start();
}
/// <summary>
/// 充电机通讯连接
/// </summary>
private void ChargerNetConnectFunc()
{
UnboundedChannelOptions options = new UnboundedChannelOptions();
options.SingleReader = true;
messageQueue = Channel.CreateUnbounded<byte[]>(options);
ChargerConnect();
}
public void ChargerConnect()
{
Task.Run(() => ConsumeMessagesThread());
while (true)
{
//if(messageQueue.)
}
}
public async Task ConsumeMessagesThread()
{
while (await messageQueue.Reader.WaitToReadAsync())
{
while (messageQueue.Reader.TryRead(out var message))
{
//Client_DataReceived(message);
}
}
}
}
}

@ -28,6 +28,8 @@ namespace HybirdFrameworkServices
public byte LoginVerify { get; set; } public byte LoginVerify { get; set; }
/// <summary> /// <summary>
/// 加密标识 /// 加密标识
/// <code>0-不加密</code>
/// <code>1-ASE 加密</code>
/// </summary> /// </summary>
public byte EncryptionFlag { get; set; } public byte EncryptionFlag { get; set; }
/// <summary> /// <summary>

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybirdFrameworkServices.Charger.BatCharging.Service
{
public static class BcdTimeConverter
{
public static long ConvertToBcdTime(DateTime dateTime)
{
// 将DateTime的各个部分分离出来
int year = dateTime.Year;
int month = dateTime.Month;
int day = dateTime.Day;
int hour = dateTime.Hour;
int minute = dateTime.Minute;
int second = dateTime.Second;
int millisecond = dateTime.Millisecond;
// BCD编码转换函数
byte BcdEncode(int value)
{
return (byte)((value / 10 * 16) + (value % 10));
}
// 构造BCD时间
// 注意:这里假设毫秒只取前两位(十位和个位),忽略剩余的毫秒数
byte secondTens = BcdEncode(second / 10);
byte secondUnits = BcdEncode(second % 10);
byte minuteTens = BcdEncode(minute / 10);
byte minuteUnits = BcdEncode(minute % 10);
byte hourTens = BcdEncode(hour / 10);
byte hourUnits = BcdEncode(hour % 10);
byte dayTens = BcdEncode(day / 10);
byte dayUnits = BcdEncode(day % 10);
byte monthTens = BcdEncode(month / 10);
byte monthUnits = BcdEncode(month % 10);
byte yearTens = BcdEncode(year / 10);
byte yearUnits = BcdEncode(year % 10);
// 组合成一个8字节的数
long bcdTime = (long)secondTens << 56 | (long)secondUnits << 52 |
(long)minuteTens << 48 | (long)minuteUnits << 44 |
(long)hourTens << 40 | (long)hourUnits << 36 |
(long)dayTens << 32 | (long)dayUnits << 28 |
(long)monthTens << 24 | (long)monthUnits << 20 |
(long)yearTens << 16 | (long)yearUnits;
return bcdTime;
}
public static byte[] ConvertToBcdTimeByte(DateTime dateTime)
{
// 将DateTime的各个部分分离出来
int year = dateTime.Year;
int month = dateTime.Month;
int day = dateTime.Day;
int hour = dateTime.Hour;
int minute = dateTime.Minute;
int second = dateTime.Second;
int millisecond = dateTime.Millisecond;
byte[] bytes= new byte[8];
bytes[0]= (byte)year;
bytes[1]= (byte)month;
bytes[2]= (byte)day;
bytes[3]= (byte)hour;
bytes[4]= (byte)minute;
bytes[5]= (byte)second;
bytes[6]= (byte)0;
bytes[7]= (byte)0;
return bytes;
}
}
}

@ -10,6 +10,7 @@ using Newtonsoft.Json;
using System.Linq; using System.Linq;
using DotNetty.Transport.Channels; using DotNetty.Transport.Channels;
using HybirdFrameworkServices.Netty; using HybirdFrameworkServices.Netty;
using HybirdFrameworkServices.Charger.BatCharging.Service;
namespace HybirdFrameworkServices namespace HybirdFrameworkServices
{ {
@ -100,6 +101,24 @@ namespace HybirdFrameworkServices
} }
} }
} }
/// <summary>
/// 线程是否启动
/// </summary>
private bool _thread_start;
/// <summary>
/// 线程是否启动
/// </summary>
public bool F_ThreadStart
{
get { return _thread_start; }
set
{
lock (lockObj)
{
_thread_start = value;
}
}
}
/// <summary> /// <summary>
/// 是否与充电机已经鉴权 /// 是否与充电机已经鉴权
@ -573,16 +592,7 @@ namespace HybirdFrameworkServices
#region 通讯线程 #region 通讯线程
/// <summary> /// <summary>
/// 充电机心跳线程和断线线程 /// 充电机线程启动
/// </summary>
public void ChargerNetHeartBeatThread()
{
Thread chrgConnectedThread = new Thread(ChargerHeartBeatFunc);
chrgConnectedThread.IsBackground = true;
chrgConnectedThread.Start();
}
/// <summary>
/// 充电机判断是否断线线程
/// </summary> /// </summary>
public void ChargerNetCheckThread() public void ChargerNetCheckThread()
{ {
@ -590,30 +600,19 @@ namespace HybirdFrameworkServices
chargerThread.IsBackground = true; chargerThread.IsBackground = true;
chargerThread.Start(); chargerThread.Start();
} }
/// <summary>
/// 充电机的心跳方法
/// </summary>
public void ChargerHeartBeatFunc()
{
while (F_IsAuthed)
{
Thread.Sleep(2000);
byte[] bytes = Send101(F_Accumulation);
if (Server != null)
{
Server.Send(bytes);
}
}
}
/// <summary> /// <summary>
/// 充电机判断是否断线线程.充电机在连接情况下30秒未收到信息则认为断线需要重新连接 /// 充电机判断是否断线线程.充电机在连接情况下30秒未收到信息则认为断线需要重新连接
/// 读取发送到此充电机的报文
/// </summary> /// </summary>
private void ChargerNetCheckFunc() private void ChargerNetCheckFunc()
{ {
while (F_IsAuthed) while (F_ThreadStart)
{
//if (F_IsAuthed)//是否鉴权
// if (F_NetConnected)//是否连接
if (F_NetConnected)//是否连接
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
@ -622,32 +621,22 @@ namespace HybirdFrameworkServices
if (seconds >= _net_check_time_out) if (seconds >= _net_check_time_out)
{ {
//ChargerDisConnect(); //ChargerDisConnect();
Server.Disconnect(F_IPAddr);
} }
} }
}
} }
#endregion 通讯线程 #endregion 通讯线程
#region 数据接收 #region 数据接收
public void decode(string IP, string port, byte[] data) public void decode(byte[] data)
{ {
switch (IP)
{
case "1":
break;
case "2":
break;
case "3":
break;
case "4":
break;
case "5":
break;
}
int func = (ushort)(data[6] + (data[6 + 1] << 8)); int func = (ushort)(data[6] + (data[6 + 1] << 8));
F_RecvingDataTime = DateTime.Now; F_RecvingDataTime = DateTime.Now;
if (func == 106 || F_IsAuthed)
switch (func) switch (func)
{ {
#region 设置/查询工作参数和命令 #region 设置/查询工作参数和命令
@ -712,7 +701,7 @@ namespace HybirdFrameworkServices
if (Server != null) if (Server != null)
{ {
Server.Send(bytes); Send(bytes);
} }
} }
break; break;
@ -726,16 +715,52 @@ namespace HybirdFrameworkServices
} }
break; break;
case 106: case 106:
//106签到鉴权
{ {
CMD106 CMD106 = ConCMD106(data); CMD106 CMD106 = ConCMD106(data);
string result = "(CMD=10)充电桩签到信息上报 - 接收字节内容:" + ByteUtils.BytesToHexStr(data) + ""; string result = "(CMD=10)充电桩签到信息上报 - 接收字节内容:" + ByteUtils.BytesToHexStr(data) + "";
result += "\r\n" + "(CMD=10)充电桩签到信息上报对象:" + JsonConvert.SerializeObject(CMD106); result += "\r\n" + "(CMD=10)充电桩签到信息上报对象:" + JsonConvert.SerializeObject(CMD106);
//Log.LogInstance.WriteLog(result, LogType.Information, "Charger" + "充电机编码"); //Log.LogInstance.WriteLog(result, LogType.Information, "Charger" + "充电机编码");
if (CMD106 != null) if (CMD106 != null)
{
//回复106签到报文
{ {
F_EqmCode = CMD106.ASCIINum; F_EqmCode = CMD106.ASCIINum;
F_Sign = CMD106.Sign == 1 ? true : false; F_Sign = CMD106.Sign == 1 ? true : false;
F_IsAuthed = true; F_IsAuthed = true;
CMD105 CMD = new CMD105();
CMD.NumResponse = (uint)new Random().Next();
CMD.LoginVerify = 0;
CMD.EncryptionFlag = 0;
CMD.RSAComModule = "";
CMD.RSAComSecret = 0;
CMD.RSAComSecret = 0;
CMD.StSign = 0;
CMD.BCDTime = (ulong)BcdTimeConverter.ConvertToBcdTime(DateTime.Now);
CMD.MessageUpload = 0;
CMD.AESSecretKey = "";
byte[] bytes = Send105(CMD);
if (Server != null)
{
Server.Send(bytes);
}
}
//CMD3对时报文
{
byte type = 1;//0-查询 1-设置
uint startAddress = 2;//设置/查询参数启始地址
byte[] setData = new byte[8];//设置数据
setData = BcdTimeConverter.ConvertToBcdTimeByte(DateTime.Now);
byte[] bytes = Send3(type, startAddress, setData);
if (Server != null)
{
Server.Send(bytes);
}
}
} }
} }
break; break;
@ -1019,6 +1044,10 @@ namespace HybirdFrameworkServices
#endregion 数据接收 #endregion 数据接收
#region 数据发送 #region 数据发送
public void Send(byte[] bytes)
{
Server.Send(bytes, ID);
}
#region 服务器向充电桩设置/查询工作参数和命令 #region 服务器向充电桩设置/查询工作参数和命令
/// <summary> /// <summary>

@ -58,7 +58,7 @@ namespace HybirdFrameworkServices.Netty
pipeline.AddLast(new CustomFrameDecoder(new IByteBuffer[] { delimiter }, false, false)); pipeline.AddLast(new CustomFrameDecoder(new IByteBuffer[] { delimiter }, false, false));
pipeline.AddLast(new CustomFrameEncoder()); pipeline.AddLast(new CustomFrameEncoder());
//// 添加客户端连接监控Handler //// 添加客户端连接监控Handler
//pipeline.AddLast(new ClientConnectionMonitorHandler()); pipeline.AddLast(new ClientConnectionMonitorHandler());
//pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时 //pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时
//pipeline.AddLast(new ReconnectHandler(this)); //pipeline.AddLast(new ReconnectHandler(this));
//pipeline.AddLast(new ClientHandler(this)); //pipeline.AddLast(new ClientHandler(this));
@ -82,12 +82,15 @@ namespace HybirdFrameworkServices.Netty
channel.WriteAndFlushAsync(bytes); channel.WriteAndFlushAsync(bytes);
} }
} }
public void Send(byte[] bytes,string id) public void Send(byte[] bytes, IChannelId id)
{ {
foreach (IChannel channel in _container.Values) //foreach (IChannel channel in _container.Values)
{ //{
channel.WriteAndFlushAsync(bytes); // channel.WriteAndFlushAsync(bytes);
} //}
if (_container.ContainsKey(id))
_container[id].WriteAndFlushAsync(bytes);
} }
/// <summary> /// <summary>

@ -1,4 +1,5 @@
using DotNetty.Transport.Channels; using DotNetty.Buffers;
using DotNetty.Transport.Channels;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -19,7 +20,6 @@ namespace HybirdFrameworkServices
public override void HandlerAdded(IChannelHandlerContext ctx) public override void HandlerAdded(IChannelHandlerContext ctx)
{ {
Console.WriteLine("Client connected: " + ctx.Channel.RemoteAddress); Console.WriteLine("Client connected: " + ctx.Channel.RemoteAddress);
string input = ctx.Channel.RemoteAddress.ToString(); string input = ctx.Channel.RemoteAddress.ToString();
// 正则表达式匹配IPv4地址和端口号 // 正则表达式匹配IPv4地址和端口号
@ -31,10 +31,12 @@ namespace HybirdFrameworkServices
switch (ipAddress) switch (ipAddress)
{ {
case "127.0.0.1": case "127.0.0.1":
CmnChargingsEqmInfo._ID = ctx.Channel.Id; CmnChargingsEqmInfo._CHR01.F_ThreadStart = true;
CmnChargingsEqmInfo._CHR0IPADDR = ipAddress; CmnChargingsEqmInfo._CHR01.F_NetConnected = true;
CmnChargingsEqmInfo._CHR0PORT = Convert.ToInt32(match.Groups[3].Value); CmnChargingsEqmInfo._CHR01.F_IPAddr = ipAddress;
CmnChargingsEqmInfo._CHR01.ChargerNetHeartBeatThread(); CmnChargingsEqmInfo._CHR01.F_Port = Convert.ToInt32(match.Groups[3].Value);
CmnChargingsEqmInfo._CHR01.F_RecvingDataTime = DateTime.Now;
CmnChargingsEqmInfo._CHR01.ChargerNetCheckThread();
break; break;
case "127.0.0.2": case "127.0.0.2":
break; break;
@ -70,7 +72,9 @@ namespace HybirdFrameworkServices
switch (ipAddress) switch (ipAddress)
{ {
case "127.0.0.1": case "127.0.0.1":
CmnChargingsEqmInfo._CHR01 = null; CmnChargingsEqmInfo._CHR01.F_ThreadStart = false;
CmnChargingsEqmInfo._CHR01.F_NetConnected = false;
CmnChargingsEqmInfo._CHR01.F_IsAuthed = false;
break; break;
case "127.0.0.2": case "127.0.0.2":
break; break;

@ -28,7 +28,6 @@ namespace HybirdFrameworkServices
protected override void Decode(IChannelHandlerContext ctx, IByteBuffer buffer, List<object> output) protected override void Decode(IChannelHandlerContext ctx, IByteBuffer buffer, List<object> output)
{ {
// 查找分隔符 // 查找分隔符
IByteBuffer delimiter = FindDelimiter(buffer); IByteBuffer delimiter = FindDelimiter(buffer);
if (delimiter != null) if (delimiter != null)
@ -62,18 +61,6 @@ namespace HybirdFrameworkServices
buffer.ReadBytes(bytes); buffer.ReadBytes(bytes);
{ {
string input = ctx.Channel.RemoteAddress.ToString();
// 正则表达式匹配IPv4地址和端口号
string pattern = @"\[(::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]:(\d+)";
Match match = Regex.Match(input, pattern);
// 获取IP地址不包括IPv6前缀
string ipAddress = match.Groups[2].Value;
// 获取端口号
string port = match.Groups[3].Value;
int checksum = 0; int checksum = 0;
for (int i = 6; i < bytes.Count() - 1; i++)//这里有校验域所以减一 for (int i = 6; i < bytes.Count() - 1; i++)//这里有校验域所以减一
{ {
@ -94,11 +81,45 @@ namespace HybirdFrameworkServices
byteList.Remove(8);//移除前面两个长度 byteList.Remove(8);//移除前面两个长度
bytes = byteList.ToArray(); bytes = byteList.ToArray();
new ChargerMgrTool().decode(ipAddress, port, bytes); CmnChargingsEqmInfo._CHR01.decode(bytes);
} }
else //不加密 else //不加密
{ {
new ChargerMgrTool().decode(ipAddress, port, bytes); //CmnChargingsEqmInfo._CHR01.decode(bytes);
string input = ctx.Channel.RemoteAddress.ToString();
// 正则表达式匹配IPv4地址和端口号
string pattern = @"\[(::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]:(\d+)";
Match match = Regex.Match(input, pattern);
// 获取IP地址不包括IPv6前缀
string ipAddress = match.Groups[2].Value;
switch (ipAddress)
{
case "127.0.0.1":
CmnChargingsEqmInfo._CHR01.ID = ctx.Channel.Id;
CmnChargingsEqmInfo._CHR01.decode(bytes);
break;
case "127.0.0.2":
CmnChargingsEqmInfo._CHR02.ID = ctx.Channel.Id;
CmnChargingsEqmInfo._CHR02.decode(bytes);
break;
case "127.0.0.3":
CmnChargingsEqmInfo._CHR03.ID = ctx.Channel.Id;
CmnChargingsEqmInfo._CHR03.decode(bytes);
break;
case "127.0.0.4":
break;
case "127.0.0.5":
break;
case "127.0.0.6":
break;
case "127.0.0.7":
break;
case "127.0.0.8":
break;
}
} }
} }
//ctx.Channel.WriteAndFlushAsync(bytes); //ctx.Channel.WriteAndFlushAsync(bytes);

@ -1,6 +1,7 @@
using Autofac; using Autofac;
using HybirdFrameworkEntity; using HybirdFrameworkEntity;
using HybirdFrameworkServices; using HybirdFrameworkServices;
using HybirdFrameworkServices.Charger.BatCharging.Manager;
using HybirdFrameworkServices.Netty; using HybirdFrameworkServices.Netty;
using HybirdFrameworkServices.System; using HybirdFrameworkServices.System;
using log4net; using log4net;
@ -47,7 +48,7 @@ public partial class Form1 : Form
Server.connect(port); Server.connect(port);
} }
#region #region 按钮方法
private void btnCmd1_Click(object sender, EventArgs e) private void btnCmd1_Click(object sender, EventArgs e)
{ {
byte type = 1;//ÀàÐÍ 0-²éѯ/1-ÉèÖà byte type = 1;//ÀàÐÍ 0-²éѯ/1-ÉèÖÃ
@ -327,8 +328,6 @@ public partial class Form1 : Form
Server.Send(bytes); Server.Send(bytes);
} }
} }
#endregion
private void btnCmd205_Click(object sender, EventArgs e) private void btnCmd205_Click(object sender, EventArgs e)
{ {
uint value03 = 0; uint value03 = 0;
@ -526,4 +525,5 @@ public partial class Form1 : Form
Server.Send(bytes); Server.Send(bytes);
} }
} }
#endregion
} }
Loading…
Cancel
Save