diff --git a/ConsoleStarter/ConsoleStarter.csproj b/ConsoleStarter/ConsoleStarter.csproj index f422989..8ac72a1 100644 --- a/ConsoleStarter/ConsoleStarter.csproj +++ b/ConsoleStarter/ConsoleStarter.csproj @@ -15,6 +15,8 @@ + + diff --git a/ConsoleStarter/ExportDb.cs b/ConsoleStarter/ExportDb.cs new file mode 100644 index 0000000..f2524ed --- /dev/null +++ b/ConsoleStarter/ExportDb.cs @@ -0,0 +1,62 @@ +using log4net; +using SqlSugar; + +namespace ConsoleStarter; + +public class ExportDb +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(ExportDb)); + + private SqlSugarClient Db = new(new ConnectionConfig + { + ConnectionString = + "server=106.12.36.89;Database=chassis_track_swap0;Uid=remote_user;Pwd=Rszn123;Charset=utf8;", + DbType = DbType.MySql, + IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute + }); + + private static readonly string[] UsedTable = new[] + { + "t_bs_charging_bin_info", + "t_bs_cloud_charge_model_recv_record", + "t_bs_cloud_elec_price_recv_record", + "t_bs_eqm_fault_base_info", + "t_bs_net_cloud_param_info", + "t_bs_net_eqm_param_info", + "t_bs_station_config_info", + "t_bs_station_elec_price_info", + "t_bs_station_info", + "t_cb_amt_order_info", + "t_cb_station_order_batt_log_info", + "t_cb_station_order_sended_log", + "t_cb_station_order_state_log", + "t_fl_repaired_info", + "t_fl_un_repair_info", + "t_rm_charger_record_report", + "t_ss_authority_to_role", + "t_ss_button_info", + "t_ss_menu_info", + "t_ss_role_info", + "t_ss_user_info", + "t_ss_user_to_role" + }; + + public void Export() + { + List tableInfoList = Db.DbMaintenance.GetTableInfoList(false); + foreach (DbTableInfo tableInfo in tableInfoList) + { + if (UsedTable.Contains(tableInfo.Name)) + { + Log.Info($"{tableInfo.Name}:{tableInfo.Description}"); + + List columnInfos = Db.DbMaintenance.GetColumnInfosByTableName(tableInfo.Name, false); + foreach (DbColumnInfo columnInfo in columnInfos) + { + Log.Info($" {columnInfo.DbColumnName}:{columnInfo.ColumnDescription}"); + } + } + } + } +} \ No newline at end of file diff --git a/ConsoleStarter/Program.cs b/ConsoleStarter/Program.cs index 0b92eeb..689e389 100644 --- a/ConsoleStarter/Program.cs +++ b/ConsoleStarter/Program.cs @@ -1,49 +1,23 @@ // See https://aka.ms/new-console-template for more information using System.Diagnostics; -using System.IO.Pipes; -using HslCommunication.Core; +using ConsoleStarter; using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.Utils; using HybirdFrameworkDriver.ModbusTcpMaster; +using log4net.Config; internal class Program { public static void Main(string[] args) { - ModbusTcpMaster master = new ModbusTcpMaster() - { - Ip = "192.168.1.5", - //默认DataFormat.ABCD - //DataFormat = DataFormat.ABCD, - ReadAction = ReadFunc - }; - - bool connected = master.Connect(); - Debug.Assert(connected, "连接modbus server 失败"); - - #region 测试写 - WaterCoolData coolData = new WaterCoolData(); - - //写入ushort - coolData.ushortType.Value = 18; - bool writeResult4 = master.WriteValue(coolData.ushortType); - Debug.Assert(writeResult4, "写入失败"); - //写入byte 0-8 byte[1] - coolData.Status.Value = 12; - bool writeResult1 = master.WriteValue(coolData.Status); - Debug.Assert(writeResult1, "写入失败"); - //写入bit - coolData.DraughtFan1.Value = true; - bool writeResult3 = master.WriteValue(coolData.DraughtFan1); - Debug.Assert(writeResult3, "写入失败"); + XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + @"\log4net.xml")); + ExportDb exportDb = new ExportDb(); + exportDb.Export(); + } - coolData.Temperature1.Value = 12.7f; - bool writeResult5 = master.WriteValue(coolData.Temperature1); - Debug.Assert(writeResult5, "写入失败"); + #region test - #endregion 测试写 - } private static WaterCoolData coolData = new WaterCoolData(); private static void ReadFunc(ModbusTcpMaster master) { @@ -156,6 +130,8 @@ internal class Program Console.WriteLine(BitUtls.BytesToHexStr(bytes)); } + + #endregion } public struct EncodeData diff --git a/HybirdFrameworkCore/Autofac/AutofacModuleRegister.cs b/HybirdFrameworkCore/Autofac/AutofacModuleRegister.cs index 52e89c1..60a7306 100644 --- a/HybirdFrameworkCore/Autofac/AutofacModuleRegister.cs +++ b/HybirdFrameworkCore/Autofac/AutofacModuleRegister.cs @@ -8,7 +8,7 @@ namespace HybirdFrameworkCore.Autofac { public class AutofacModuleRegister : Module { - private readonly ILog Log = LogManager.GetLogger(typeof(AutofacModuleRegister)); + private static readonly ILog Log = LogManager.GetLogger(typeof(AutofacModuleRegister)); protected override void Load(ContainerBuilder builder) { @@ -68,7 +68,7 @@ namespace HybirdFrameworkCore.Autofac if (defaultList.Count > 0) { - builder.RegisterTypes(defaultList.ToArray()).SingleInstance() + builder.RegisterTypes(defaultList.ToArray()).AsSelf().SingleInstance() .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); //支持属性注入依赖重复 } @@ -83,39 +83,27 @@ namespace HybirdFrameworkCore.Autofac } else { - Type? iInterface = type.GetInterface("HybirdFrameworkDriver.TcpServer.IMsgHandler"); - if (iInterface != null) - { - builder.RegisterType(type).As(iInterface).InstancePerDependency() + builder.RegisterType(type).InstancePerDependency() .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); } + } + } - iInterface = type.GetInterface("HybirdFrameworkDriver.TcpServer.IDecoder"); - if (iInterface != null) + if (instancePerLifetimeScopeList.Count > 0) { - builder.RegisterType(type).As(iInterface).InstancePerDependency() - .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); + builder.RegisterTypes(instancePerLifetimeScopeList.ToArray()).InstancePerMatchingLifetimeScope() + .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); //支持属性注入依赖重复 + } } - iInterface = type.GetInterface("HybirdFrameworkDriver.TcpServer.IEncoder"); + private void RegisterToInterface(String interfaceName, Type type, ContainerBuilder builder) + { + Type? iInterface = type.GetInterface(interfaceName); if (iInterface != null) { builder.RegisterType(type).As(iInterface).InstancePerDependency() .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); } - - - builder.RegisterType(type).InstancePerDependency() - .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); - } - } - } - - if (instancePerLifetimeScopeList.Count > 0) - { - builder.RegisterTypes(instancePerLifetimeScopeList.ToArray()).InstancePerMatchingLifetimeScope() - .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); //支持属性注入依赖重复 - } } } } \ No newline at end of file diff --git a/HybirdFrameworkDriver/Common/IToBytes.cs b/HybirdFrameworkDriver/Common/IToBytes.cs new file mode 100644 index 0000000..8d13ce3 --- /dev/null +++ b/HybirdFrameworkDriver/Common/IToBytes.cs @@ -0,0 +1,6 @@ +namespace HybirdFrameworkDriver.Common; + +public interface IToBytes +{ + byte[] ToBytes(); +} \ No newline at end of file diff --git a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs index ef60ba5..cacd12e 100644 --- a/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs +++ b/HybirdFrameworkDriver/ModbusTcpMaster/ModbusTcpMaster.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections; -using HslCommunication; +using HslCommunication; using HslCommunication.Core; using HslCommunication.ModBus; using HybirdFrameworkCore.Utils; @@ -12,8 +10,8 @@ public class ModbusTcpMaster { private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusTcpMaster)); - // public string Ip { get; set; } = "127.0.0.1"; - public string Ip { get; set; } = "192.168.1.5"; + public string Ip { get; set; } = "127.0.0.1"; + public int Port { get; set; } = 502; public static DataFormat DataFormat { get; set; } = DataFormat.ABCD; @@ -21,6 +19,8 @@ public class ModbusTcpMaster public int Duration { get; set; } = 1000; public bool Connected { get; set; } = false; + public string connectId { get; set; } + public delegate void MyReadAction(ModbusTcpMaster str); public MyReadAction? ReadAction { get; set; } @@ -29,7 +29,6 @@ public class ModbusTcpMaster private ModbusTcpNet ModbusTcpNet; - ILog GetLog() { return Log; @@ -46,6 +45,7 @@ public class ModbusTcpMaster ModbusTcpNet = new ModbusTcpNet(Ip, Port); ModbusTcpNet.DataFormat = DataFormat; OperateResult result = ModbusTcpNet.ConnectServer(); + connectId = ModbusTcpNet.ConnectionId; if (result.IsSuccess) { Connected = true; @@ -185,15 +185,16 @@ public class ModbusTcpMaster else preWriteCont[i - 1] = setValue[i]; } + break; case DataFormat.BADC: Array.Copy(setValue, preWriteCont, setValue.Length); break; } + operateResult = ModbusTcpNet.Write("x=16;" + (registerNo), preWriteCont); result = operateResult.IsSuccess; } - } else if (setValue.Length == length * 2) { @@ -209,21 +210,26 @@ public class ModbusTcpMaster else preWriteCont[i - 1] = setValue[i]; } + break; case DataFormat.BADC: //Array.Copy(setValue, preWriteCont, setValue.Length); break; } + operateResult = ModbusTcpNet.Write("x=16;" + (registerNo), preWriteCont); result = operateResult.IsSuccess; } + break; case ModbusDataType.Bit: result = WriteRegisterOneBit(registerNo, start, Convert.ToBoolean(value)); break; } + return result; } + /// /// 写寄存器中的一个bit /// @@ -253,6 +259,7 @@ public class ModbusTcpMaster mask = (ushort)(~(1 << location)); registerValue1 &= mask; } + OperateResult writeResult = ModbusTcpNet.Write("x=6;" + addr, registerValue1); if (writeResult.IsSuccess) { @@ -260,7 +267,7 @@ public class ModbusTcpMaster } } } + return result; } - } \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/ChannelUtils.cs b/HybirdFrameworkDriver/Session/ChannelUtils.cs similarity index 94% rename from HybirdFrameworkDriver/TcpServer/ChannelUtils.cs rename to HybirdFrameworkDriver/Session/ChannelUtils.cs index 0bdc145..d228136 100644 --- a/HybirdFrameworkDriver/TcpServer/ChannelUtils.cs +++ b/HybirdFrameworkDriver/Session/ChannelUtils.cs @@ -1,7 +1,7 @@ using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; -namespace HybirdFrameworkDriver.TcpServer; +namespace HybirdFrameworkDriver.Session; public static class ChannelUtils { diff --git a/HybirdFrameworkDriver/TcpServer/IoSession.cs b/HybirdFrameworkDriver/Session/IoSession.cs similarity index 61% rename from HybirdFrameworkDriver/TcpServer/IoSession.cs rename to HybirdFrameworkDriver/Session/IoSession.cs index ef2a2d8..2cd6edb 100644 --- a/HybirdFrameworkDriver/TcpServer/IoSession.cs +++ b/HybirdFrameworkDriver/Session/IoSession.cs @@ -1,25 +1,30 @@ -using DotNetty.Buffers; +using System.Collections.Concurrent; +using DotNetty.Buffers; using DotNetty.Transport.Channels; using log4net; -namespace HybirdFrameworkDriver.TcpServer; - +namespace HybirdFrameworkDriver.Session; public class IoSession { - private readonly ILog Log = LogManager.GetLogger(typeof(IoSession)); + private static readonly ILog Log = LogManager.GetLogger(typeof(IoSession)); - private IChannel Channel { get; } + public IChannel Channel { get; } private String IpAddr { get; } public String Key { get; set; } + private bool Reconnected { get; set; } + //业务数据 + public ConcurrentDictionary BusinessMap { get; } = new ConcurrentDictionary(); + public IoSession(IChannel channel) { this.Channel = channel; this.IpAddr = ChannelUtils.GetIp(channel); } + public void Send(IByteBuffer buffer) { Channel.WriteAndFlushAsync(buffer); diff --git a/HybirdFrameworkDriver/Session/ModbusSession.cs b/HybirdFrameworkDriver/Session/ModbusSession.cs new file mode 100644 index 0000000..3c39c70 --- /dev/null +++ b/HybirdFrameworkDriver/Session/ModbusSession.cs @@ -0,0 +1,37 @@ +using System.Collections.Concurrent; +using DotNetty.Buffers; +using DotNetty.Transport.Channels; +using HybirdFrameworkDriver.ModbusTcpMaster; +using log4net; + +namespace HybirdFrameworkDriver.Session; + + +public class ModbusSession +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusSession)); + + public ModbusTcpMaster.ModbusTcpMaster ModbusTcpMaster; + private String IpAddr { get; } + public String Key { get; set; } + + public ConcurrentDictionary BusinessMap { get;set; } + public ModbusSession(ModbusTcpMaster.ModbusTcpMaster modbusTcpMaster) + { + this.ModbusTcpMaster = modbusTcpMaster; + this.IpAddr = modbusTcpMaster.Ip; + this.Key = modbusTcpMaster.connectId; + } + + + public bool Write(ModbusProperty property) + { + return ModbusTcpMaster.WriteValue(property); + } + public byte[]? Read(int registerNo, int length) + { + return ModbusTcpMaster.BatchRead(registerNo,length); + } + + +} \ No newline at end of file diff --git a/HybirdFrameworkDriver/Session/SessionMgr.cs b/HybirdFrameworkDriver/Session/SessionMgr.cs new file mode 100644 index 0000000..b256b32 --- /dev/null +++ b/HybirdFrameworkDriver/Session/SessionMgr.cs @@ -0,0 +1,154 @@ +using System.Collections.Concurrent; +using DotNetty.Buffers; +using DotNetty.Transport.Channels; +using log4net; + +namespace HybirdFrameworkDriver.Session; + +public class SessionMgr +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(SessionMgr)); + + private static readonly ConcurrentDictionary Dictionary = + new ConcurrentDictionary(); + + private static readonly ConcurrentDictionary ModbusDictionary = + new ConcurrentDictionary(); + + public ConcurrentDictionary? BusinessMap { get; set; } + + public static IoSession? GetSession(string key) + { + if (Dictionary.ContainsKey(key)) + { + IoSession? value; + Dictionary.TryGetValue(key, out value); + + return value; + } + + return null; + } + + public static List GetSessionList() + { + return Dictionary.Values.ToList(); + } + + public static ModbusSession GetModbusSession(string key) + { + if (ModbusDictionary.ContainsKey(key)) + { + ModbusSession value; + ModbusDictionary.TryGetValue(key, out value); + + return value; + } + + return null; + } + + public static void RegisterSession(IChannel channel, IoSession ioSession) + { + var oldKey = ioSession.Key; + if (oldKey != null) + { + IoSession? session; + Dictionary.Remove(oldKey, out session); + } + + ChannelUtils.AddChannelSession(channel, ioSession); + ioSession.Key = channel.Id.ToString(); + Dictionary.AddOrUpdate(channel.Id.ToString(), ioSession, (k, oldSession) => ioSession); + } + + + public static void RegisterModbusSession(string key, ModbusSession ioSession) + { + var oldKey = ioSession.Key; + if (oldKey != null) + { + ModbusSession? session; + ModbusDictionary.Remove(oldKey, out session); + } + + ioSession.Key = key; + ModbusDictionary.AddOrUpdate(key, ioSession, (k, oldSession) => ioSession); + } + + public static void UnregisterSession(IChannel channel) + { + IoSession session = ChannelUtils.GetSessionBy(channel); + IoSession? outSession; + Dictionary.Remove(session.Key, out outSession); + session.Close(); + } + + + public static void Broadcast(IByteBuffer buffer, ConcurrentDictionary dictionary) + { + foreach (IoSession session in dictionary.Values) + { + session.Send(buffer); + } + } + + public static Object GetAttr(IoSession session, String key) + { + Object? obj; + session.BusinessMap.TryGetValue(key, out obj); + return obj; + } + + public static void SetAttr(IoSession session, String key, Object obj) + { + session.BusinessMap.TryAdd(key, obj); + } + + public static Object GetAttrByKey(String? key, String mapKey) + { + if (!string.IsNullOrEmpty(key)) + { + Dictionary.TryGetValue(key, out IoSession? session); + + if (session != null) + { + session.BusinessMap.TryGetValue(mapKey, out Object? obj); + + if (obj != null) + { + return (int)obj; + } + } + } + + return 0; + } + + public static void SetAttrModbus(ModbusSession session, String key, Object obj) + { + if (session.BusinessMap == null) + { + session.BusinessMap = new ConcurrentDictionary(); + } + + session.BusinessMap.TryAdd(key, obj); + } + + public static Object GetAttrModbus(String key, String mapKey) + { + ModbusDictionary.TryGetValue(key, out ModbusSession? session); + + if (session != null) + { + session.BusinessMap.TryGetValue(mapKey, out Object? obj); + + if (obj != null) + { + return (int)obj; + } + } + + return 0; + } +} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpClient/ClientListenerHandler.cs b/HybirdFrameworkDriver/TcpClient/ClientListenerHandler.cs new file mode 100644 index 0000000..7a934aa --- /dev/null +++ b/HybirdFrameworkDriver/TcpClient/ClientListenerHandler.cs @@ -0,0 +1,73 @@ +using System.Net; +using Autofac; +using DotNetty.Codecs; +using DotNetty.Handlers.Timeout; +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Autofac; +using HybirdFrameworkDriver.Session; +using log4net; + +namespace HybirdFrameworkDriver.TcpClient; + +public class ClientListenerHandler : ChannelHandlerAdapter where TH : IChannelHandler + where TD : ByteToMessageDecoder, new() + where TE : ChannelHandlerAdapter, new() +{ + private static readonly ILog Log = LogManager.GetLogger(typeof(ClientListenerHandler)); + + public override void ChannelRegistered(IChannelHandlerContext context) + { + base.ChannelRegistered(context); + Log.Info("register " + context.Channel); + } + + public override void ChannelUnregistered(IChannelHandlerContext context) + { + base.ChannelUnregistered(context); + Log.Info("unregister " + context.Channel); + } + + public override void ChannelActive(IChannelHandlerContext context) + { + base.ChannelActive(context); + SessionMgr.RegisterSession(context.Channel, new IoSession(context.Channel)); + Log.Info("active " + context.Channel); + } + + public override void ChannelInactive(IChannelHandlerContext context) + { + base.ChannelInactive(context); + var ioSession = SessionMgr.GetSession(context.Channel.Id.ToString()); + SessionMgr.UnregisterSession(context.Channel); + Log.Info("inactive " + context.Channel); + //处理重连 + + TcpClient tcpClient = AppInfo.Container.Resolve>(); + IPEndPoint channelRemoteAddress = (IPEndPoint)ioSession.Channel.RemoteAddress; + tcpClient.InitBootstrap(channelRemoteAddress.Address.ToString(), channelRemoteAddress.Port); + tcpClient.Connect(); + } + + public override void UserEventTriggered(IChannelHandlerContext context, object evt) + { + if (evt is IdleStateEvent) + { + if (context.Channel.Open) + { + context.Channel.CloseAsync(); + context.Channel.CloseCompletion.Wait(); + Log.Info($"channel {context.Channel.Id} timeout close"); + } + } + + base.UserEventTriggered(context, evt); + Log.Info("UserEventTriggered " + context.Channel); + } + + public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) + { + base.ExceptionCaught(context, exception); + context.Channel.CloseAsync(); + Log.Info("exception " + context.Channel); + } +} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpClient/TcpClient.cs b/HybirdFrameworkDriver/TcpClient/TcpClient.cs new file mode 100644 index 0000000..08820da --- /dev/null +++ b/HybirdFrameworkDriver/TcpClient/TcpClient.cs @@ -0,0 +1,148 @@ +using System.Net; +using System.Reflection; +using Autofac; +using Autofac.Core; +using DotNetty.Codecs; +using DotNetty.Handlers.Timeout; +using DotNetty.Transport.Bootstrapping; +using DotNetty.Transport.Channels; +using DotNetty.Transport.Channels.Sockets; +using HybirdFrameworkCore.Autofac; +using HybirdFrameworkCore.Autofac.Attribute; +using log4net; + +namespace HybirdFrameworkDriver.TcpClient; + +public class TcpClient where TH : IChannelHandler where TD: ByteToMessageDecoder,new() where TE: ChannelHandlerAdapter, new() +{ + private Bootstrap? _bootstrap; + + public IChannel Channel { get; set; } + + public bool Connected { get; set; } = false; + + public string Host { get; set; } + public int Port { get; set; } + + private static readonly ILog Log = LogManager.GetLogger(typeof(TcpClient)); + + public void InitBootstrap(string host, int port) + { + Host = host; + Port = port; + _bootstrap = new Bootstrap(); + _bootstrap + .Group(new MultithreadEventLoopGroup()) + .Channel() + .Option(ChannelOption.TcpNodelay, true) + .Handler(new ActionChannelInitializer(channel => + { + var clientListenerHandler = new ClientListenerHandler(); + + IChannelPipeline pipeline = channel.Pipeline; + // 监听器 + pipeline.AddLast(clientListenerHandler); + pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时 + + + // 可以添加编解码器等 + ResolveDecode(pipeline); + ResolveEncode(pipeline); + + ResolveHandler(pipeline); + })); + } + + + private void ResolveEncode(IChannelPipeline pipeline) + { + pipeline.AddLast(new TE()); + } + + private void ResolveDecode(IChannelPipeline pipeline) + { + pipeline.AddLast(new TD()); + } + + private void ResolveHandler(IChannelPipeline pipeline) + { + + List list = new List(); + + foreach (IComponentRegistration reg in AppInfo.Container.ComponentRegistry.Registrations) + { + foreach (Service service in reg.Services) + { + if (service is TypedService ts) + { + if (MatchHandlers(ts)) + { + list.Add(ts.ServiceType); + } + } + } + } + + List handlers = new List(); + foreach (var type in list) + { + object resolve = AppInfo.Container.Resolve(type); + handlers.Add((TH) resolve); + } + + handlers.Sort((handler, msgHandler) => + { + OrderAttribute? orderAttribute1 = handler.GetType().GetCustomAttribute(); + OrderAttribute? orderAttribute2 = msgHandler.GetType().GetCustomAttribute(); + int h1Order = orderAttribute1?.Order ?? 0; + int h2Order = orderAttribute2?.Order ?? 0; + return h1Order.CompareTo(h2Order); + }); + foreach (var msgHandler in handlers) + { + pipeline.AddLast((IChannelHandler)msgHandler); + } + } + + private bool MatchHandlers(TypedService ts) + { + Type[] interfaces = ts.ServiceType.GetInterfaces(); + if (interfaces.Length > 0) + { + foreach (Type type in interfaces) + { + if (type == typeof(TH)) + { + return true; + } + } + } + + return false; + } + + + public void Connect() + { + Connected = false; + int num = 1; + while (!Connected) + { + Task task = _bootstrap!.ConnectAsync(new IPEndPoint(IPAddress.Parse(Host), Port)); + + Channel = task.Result; + Connected = Channel.Open; + + if (Connected) + { + break; + } + + Thread.Sleep(5000); + num++; + } + + } + + +} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/IDecoder.cs b/HybirdFrameworkDriver/TcpServer/IDecoder.cs deleted file mode 100644 index 65c6d68..0000000 --- a/HybirdFrameworkDriver/TcpServer/IDecoder.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace HybirdFrameworkDriver.TcpServer; - -public interface IDecoder -{ -} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/IEncoder.cs b/HybirdFrameworkDriver/TcpServer/IEncoder.cs deleted file mode 100644 index 9cbfde5..0000000 --- a/HybirdFrameworkDriver/TcpServer/IEncoder.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace HybirdFrameworkDriver.TcpServer; - -public interface IEncoder -{ - -} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/IMsgHandler.cs b/HybirdFrameworkDriver/TcpServer/IMsgHandler.cs deleted file mode 100644 index ef24d8b..0000000 --- a/HybirdFrameworkDriver/TcpServer/IMsgHandler.cs +++ /dev/null @@ -1,7 +0,0 @@ -using DotNetty.Transport.Channels; - -namespace HybirdFrameworkDriver.TcpServer; - -public interface IMsgHandler -{ -} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/ServerListenerHandler.cs b/HybirdFrameworkDriver/TcpServer/ServerListenerHandler.cs index 82d6f06..4fb6914 100644 --- a/HybirdFrameworkDriver/TcpServer/ServerListenerHandler.cs +++ b/HybirdFrameworkDriver/TcpServer/ServerListenerHandler.cs @@ -1,14 +1,18 @@ -using DotNetty.Transport.Channels; +using DotNetty.Codecs; +using DotNetty.Transport.Channels; using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.Session; using log4net; namespace HybirdFrameworkDriver.TcpServer { [Scope("InstancePerDependency")] - public class ServerListenerHandler : ChannelHandlerAdapter + public class ServerListenerHandler : ChannelHandlerAdapter where TH : IChannelHandler + where TD : ByteToMessageDecoder, new() + where TE : ChannelHandlerAdapter, new() { - private readonly ILog Log = LogManager.GetLogger(typeof(ServerListenerHandler)); + private static readonly ILog Log = LogManager.GetLogger(typeof(ServerListenerHandler)); public override void ChannelRegistered(IChannelHandlerContext context) { diff --git a/HybirdFrameworkDriver/TcpServer/SessionMgr.cs b/HybirdFrameworkDriver/TcpServer/SessionMgr.cs deleted file mode 100644 index 6bf8b0e..0000000 --- a/HybirdFrameworkDriver/TcpServer/SessionMgr.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Concurrent; -using DotNetty.Buffers; -using DotNetty.Transport.Channels; -using log4net; - -namespace HybirdFrameworkDriver.TcpServer; - -public class SessionMgr -{ - private static readonly ILog Log = LogManager.GetLogger(typeof(SessionMgr)); - - private static readonly ConcurrentDictionary Dictionary = - new ConcurrentDictionary(); - - public static void RegisterSession(IChannel channel, IoSession ioSession) - { - ioSession.Key = channel.Id.ToString(); - IoSession? session; - Dictionary.Remove(ioSession.Key, out session); - ChannelUtils.AddChannelSession(channel, ioSession); - Dictionary.AddOrUpdate(channel.Id.ToString(), ioSession, (k, oldSession) => ioSession); - } - - public static void UnregisterSession(IChannel channel) - { - IoSession session = ChannelUtils.GetSessionBy(channel); - IoSession? outSession; - Dictionary.Remove(session.Key, out outSession); - session.Close(); - } - - public static void Broadcast(IByteBuffer buffer) - { - foreach (IoSession session in Dictionary.Values) - { - session.Send(buffer); - } - } -} \ No newline at end of file diff --git a/HybirdFrameworkDriver/TcpServer/Server.cs b/HybirdFrameworkDriver/TcpServer/TcpServer.cs similarity index 62% rename from HybirdFrameworkDriver/TcpServer/Server.cs rename to HybirdFrameworkDriver/TcpServer/TcpServer.cs index 35a83b2..9e83895 100644 --- a/HybirdFrameworkDriver/TcpServer/Server.cs +++ b/HybirdFrameworkDriver/TcpServer/TcpServer.cs @@ -1,5 +1,6 @@ using System.Reflection; using Autofac; +using Autofac.Core; using DotNetty.Codecs; using DotNetty.Handlers.Logging; using DotNetty.Handlers.Timeout; @@ -15,10 +16,9 @@ namespace HybirdFrameworkDriver.TcpServer /// /// netty server /// - [Scope("InstancePerDependency")] - public class Server : IDisposable + public class TcpServer : IDisposable where TH : IChannelHandler where TD: ByteToMessageDecoder,new() where TE: ChannelHandlerAdapter, new() { - private readonly ILog Log = LogManager.GetLogger(typeof(Server)); + private static readonly ILog Log = LogManager.GetLogger(typeof(TcpServer)); static MultithreadEventLoopGroup? bossGroup; static MultithreadEventLoopGroup? workerGroup; @@ -26,7 +26,7 @@ namespace HybirdFrameworkDriver.TcpServer private int _port = 9000; - public Server() + public TcpServer() { bossGroup = new MultithreadEventLoopGroup(); workerGroup = new MultithreadEventLoopGroup(); @@ -38,7 +38,7 @@ namespace HybirdFrameworkDriver.TcpServer .Handler(new LoggingHandler()) .ChildHandler(new ActionChannelInitializer(channel => { - var serverListenerHandler = new ServerListenerHandler(); + var serverListenerHandler = new ServerListenerHandler(); IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("")); pipeline.AddLast(serverListenerHandler); @@ -53,21 +53,40 @@ namespace HybirdFrameworkDriver.TcpServer private void ResolveEncode(IChannelPipeline pipeline) { - IEncoder resolve = AppInfo.Container.Resolve(); - pipeline.AddLast((MessageToByteEncoder)resolve); + pipeline.AddLast(new TE()); } private void ResolveDecode(IChannelPipeline pipeline) { - IDecoder resolve = AppInfo.Container.Resolve(); - pipeline.AddLast((ByteToMessageDecoder)resolve); + pipeline.AddLast(new TD()); } private void ResolveHandler(IChannelPipeline pipeline) { - IEnumerable handlers = AppInfo.Container.Resolve>(); - IMsgHandler[] msgHandlers = handlers.ToArray(); - Array.Sort(msgHandlers, (handler, msgHandler) => + List list = new List(); + + foreach (IComponentRegistration reg in AppInfo.Container.ComponentRegistry.Registrations) + { + foreach (Service service in reg.Services) + { + if (service is TypedService ts) + { + if (MatchHandlers(ts)) + { + list.Add(ts.ServiceType); + } + } + } + } + + List handlers = new List(); + foreach (var type in list) + { + object resolve = AppInfo.Container.Resolve(type); + handlers.Add((TH) resolve); + } + + handlers.Sort((handler, msgHandler) => { OrderAttribute? orderAttribute1 = handler.GetType().GetCustomAttribute(); OrderAttribute? orderAttribute2 = msgHandler.GetType().GetCustomAttribute(); @@ -75,13 +94,28 @@ namespace HybirdFrameworkDriver.TcpServer int h2Order = orderAttribute2?.Order ?? 0; return h1Order.CompareTo(h2Order); }); - foreach (var msgHandler in msgHandlers) + foreach (var msgHandler in handlers) { - pipeline.AddLast((ChannelHandlerAdapter)msgHandler); + pipeline.AddLast((IChannelHandler)msgHandler); } } + + private bool MatchHandlers(TypedService ts) + { + Type[] interfaces = ts.ServiceType.GetInterfaces(); + if (interfaces.Length > 0) + { + foreach (Type type in interfaces) + { + if (type == typeof(TH)) + { + return true; + } + } + } - + return false; + } public void Start(int port) { diff --git a/HybirdFrameworkRepository/bin/Debug/net6.0/HybirdFrameworkRepository.deps.json b/HybirdFrameworkRepository/bin/Debug/net6.0/HybirdFrameworkRepository.deps.json index e543d05..3377398 100644 --- a/HybirdFrameworkRepository/bin/Debug/net6.0/HybirdFrameworkRepository.deps.json +++ b/HybirdFrameworkRepository/bin/Debug/net6.0/HybirdFrameworkRepository.deps.json @@ -208,6 +208,14 @@ } } }, + "Microsoft.Extensions.Logging.Abstractions/6.0.0": { + "runtime": { + "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "assemblyVersion": "6.0.0.0", + "fileVersion": "6.0.21.52210" + } + } + }, "Microsoft.Extensions.Primitives/7.0.0": { "dependencies": { "System.Runtime.CompilerServices.Unsafe": "6.0.0" @@ -347,6 +355,17 @@ } } }, + "Pipelines.Sockets.Unofficial/2.2.8": { + "dependencies": { + "System.IO.Pipelines": "5.0.1" + }, + "runtime": { + "lib/net5.0/Pipelines.Sockets.Unofficial.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "2.2.8.1080" + } + } + }, "SQLitePCLRaw.bundle_e_sqlite3/2.1.4": { "dependencies": { "SQLitePCLRaw.lib.e_sqlite3": "2.1.4", @@ -551,6 +570,18 @@ } } }, + "StackExchange.Redis/2.7.33": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8" + }, + "runtime": { + "lib/net6.0/StackExchange.Redis.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.7.33.41805" + } + } + }, "System.Collections/4.3.0": { "dependencies": { "Microsoft.NETCore.Platforms": "5.0.0", @@ -703,6 +734,14 @@ "System.Threading.Tasks": "4.3.0" } }, + "System.IO.Pipelines/5.0.1": { + "runtime": { + "lib/netcoreapp3.0/System.IO.Pipelines.dll": { + "assemblyVersion": "5.0.0.1", + "fileVersion": "5.0.120.57516" + } + } + }, "System.Memory/4.5.3": {}, "System.Reflection/4.3.0": { "dependencies": { @@ -895,6 +934,7 @@ "Microsoft.Extensions.Configuration.Abstractions": "7.0.0", "Microsoft.Extensions.Configuration.Json": "7.0.0", "Newtonsoft.Json": "13.0.3", + "StackExchange.Redis": "2.7.33", "log4net": "2.0.15" }, "runtime": { @@ -1022,6 +1062,13 @@ "path": "microsoft.extensions.filesystemglobbing/7.0.0", "hashPath": "microsoft.extensions.filesystemglobbing.7.0.0.nupkg.sha512" }, + "Microsoft.Extensions.Logging.Abstractions/6.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==", + "path": "microsoft.extensions.logging.abstractions/6.0.0", + "hashPath": "microsoft.extensions.logging.abstractions.6.0.0.nupkg.sha512" + }, "Microsoft.Extensions.Primitives/7.0.0": { "type": "package", "serviceable": true, @@ -1127,6 +1174,13 @@ "path": "oracle.manageddataaccess.core/3.21.100", "hashPath": "oracle.manageddataaccess.core.3.21.100.nupkg.sha512" }, + "Pipelines.Sockets.Unofficial/2.2.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "path": "pipelines.sockets.unofficial/2.2.8", + "hashPath": "pipelines.sockets.unofficial.2.2.8.nupkg.sha512" + }, "SQLitePCLRaw.bundle_e_sqlite3/2.1.4": { "type": "package", "serviceable": true, @@ -1183,6 +1237,13 @@ "path": "sqlsugarcore.kdbndp/7.4.0", "hashPath": "sqlsugarcore.kdbndp.7.4.0.nupkg.sha512" }, + "StackExchange.Redis/2.7.33": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2kCX5fvhEE824a4Ab5Imyi8DRuGuTxyklXV01kegkRpsWJcPmO6+GAQ+HegKxvXAxlXZ8yaRspvWJ8t3mMClfQ==", + "path": "stackexchange.redis/2.7.33", + "hashPath": "stackexchange.redis.2.7.33.nupkg.sha512" + }, "System.Collections/4.3.0": { "type": "package", "serviceable": true, @@ -1260,6 +1321,13 @@ "path": "system.io/4.3.0", "hashPath": "system.io.4.3.0.nupkg.sha512" }, + "System.IO.Pipelines/5.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "path": "system.io.pipelines/5.0.1", + "hashPath": "system.io.pipelines.5.0.1.nupkg.sha512" + }, "System.Memory/4.5.3": { "type": "package", "serviceable": true, diff --git a/HybirdFrameworkServices/Charger/Client/ChargerClient.cs b/HybirdFrameworkServices/Charger/Client/ChargerClient.cs new file mode 100644 index 0000000..0de0f3d --- /dev/null +++ b/HybirdFrameworkServices/Charger/Client/ChargerClient.cs @@ -0,0 +1,29 @@ +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.Session; +using HybirdFrameworkDriver.TcpClient; +using HybirdFrameworkServices.Charger.Codec; +using HybirdFrameworkServices.Charger.Handler; + +namespace HybirdFrameworkServices.Charger.Client; + +/// +/// 示例程序 +/// +[Scope("InstancePerDependency")] +public class ChargerClient : TcpClient +{ + public void SessionAttr(int sn, int fEqmTypeNo, string eqmCode, string destAddr) + { + IoSession? ioSession = SessionMgr.GetSession(this.Channel.Id.ToString()); + if (ioSession == null) + { + ioSession = new IoSession(this.Channel); + SessionMgr.RegisterSession(this.Channel, ioSession); + } + + SessionMgr.SetAttr(ioSession, "charger_sn", sn); + SessionMgr.SetAttr(ioSession, "eqm_type_no", fEqmTypeNo); + SessionMgr.SetAttr(ioSession, "eqm_code", eqmCode); + SessionMgr.SetAttr(ioSession, "dest_addr", destAddr); + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Client/ChargerServer.cs b/HybirdFrameworkServices/Charger/Client/ChargerServer.cs new file mode 100644 index 0000000..66bf615 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Client/ChargerServer.cs @@ -0,0 +1,14 @@ +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.TcpServer; +using HybirdFrameworkServices.Charger.Codec; +using HybirdFrameworkServices.Charger.Handler; + +namespace HybirdFrameworkServices.Charger.Client; + +/// +/// 示例程序 +/// +[Scope("InstancePerDependency")] +public class ChargerServer : TcpServer +{ +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Client/ClientMgr.cs b/HybirdFrameworkServices/Charger/Client/ClientMgr.cs new file mode 100644 index 0000000..dcd493f --- /dev/null +++ b/HybirdFrameworkServices/Charger/Client/ClientMgr.cs @@ -0,0 +1,29 @@ +using System.Text; +using Autofac; +using HybirdFrameworkCore.Autofac; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkServices.Charger.Msg.Host.Req; + +namespace HybirdFrameworkServices.Charger.Client; + +/// +/// 示例程序 +/// +[Scope("SingleInstance")] +public class ClientMgr +{ + public void InitClient() + { + Auth auth = new Auth(1, Encoding.UTF8.GetBytes("ddddddddd"), 1); + auth.DestAddr = new byte[] { 0x01, 0x02, 0x03 }; + + ChargerClient chargerClient2 = AppInfo.Container.Resolve(); + chargerClient2.InitBootstrap("127.0.0.1", 9998); + chargerClient2.Connect(); + chargerClient2.SessionAttr(12, 12, "12", "2"); + chargerClient2.Channel.WriteAndFlushAsync(auth); + + ChargerServer chargerServer = AppInfo.Container.Resolve(); + chargerServer.Start(9000); + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Codec/Decoder.cs b/HybirdFrameworkServices/Charger/Codec/Decoder.cs index ee1e1ea..bb230cc 100644 --- a/HybirdFrameworkServices/Charger/Codec/Decoder.cs +++ b/HybirdFrameworkServices/Charger/Codec/Decoder.cs @@ -1,16 +1,14 @@ using DotNetty.Buffers; using DotNetty.Codecs; using DotNetty.Transport.Channels; -using HybirdFrameworkCore.Autofac.Attribute; -using HybirdFrameworkDriver.TcpServer; +using HybirdFrameworkServices.Charger.Msg.Charger.Req; namespace HybirdFrameworkServices.Charger.Codec; -[Scope("InstancePerDependency")] -public class Decoder : ByteToMessageDecoder, IDecoder +public class Decoder : ByteToMessageDecoder { protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) { - output.Add(new IoSession(context.Channel)); + output.Add(new Login()); } } \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Codec/Encoder.cs b/HybirdFrameworkServices/Charger/Codec/Encoder.cs index a59d3b2..9aa7817 100644 --- a/HybirdFrameworkServices/Charger/Codec/Encoder.cs +++ b/HybirdFrameworkServices/Charger/Codec/Encoder.cs @@ -1,16 +1,14 @@ using DotNetty.Buffers; using DotNetty.Codecs; using DotNetty.Transport.Channels; -using HybirdFrameworkCore.Autofac.Attribute; -using HybirdFrameworkDriver.TcpServer; +using HybirdFrameworkDriver.Common; namespace HybirdFrameworkServices.Charger.Codec; -[Scope("InstancePerDependency")] -public class Encoder : MessageToByteEncoder, IEncoder +public class Encoder : MessageToByteEncoder { - protected override void Encode(IChannelHandlerContext context, byte[] message, IByteBuffer output) + protected override void Encode(IChannelHandlerContext context, IToBytes obj, IByteBuffer output) { - output.WriteBytes(message); + output.WriteBytes(obj.ToBytes()); } } \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Common/ChargerConst.cs b/HybirdFrameworkServices/Charger/Common/ChargerConst.cs new file mode 100644 index 0000000..2592e03 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Common/ChargerConst.cs @@ -0,0 +1,6 @@ +namespace HybirdFrameworkServices.Charger.Common; + +public class ChargerConst +{ + public static readonly byte[] ApciStartChar = { 0x68/* ,0xEE*/}; +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Handler/AuthResHandler.cs b/HybirdFrameworkServices/Charger/Handler/AuthResHandler.cs new file mode 100644 index 0000000..a83b8ac --- /dev/null +++ b/HybirdFrameworkServices/Charger/Handler/AuthResHandler.cs @@ -0,0 +1,29 @@ +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.Session; +using HybirdFrameworkServices.Charger.Msg.Charger.Resp; +using log4net; + +namespace HybirdFrameworkServices.Charger.Handler +{ + /// + /// 接收到鉴权帧 + /// + /// 1,保存日志到log + /// 2,从SessionMgr中取目的地址,解析后写入ChargerManager + /// 3,保存鉴权状态和充电状态 + /// + /// + [Order(8)] + [Scope("InstancePerDependency")] + public class AuthResHandler : SimpleChannelInboundHandler, IBaseHandler + { + private static readonly ILog Log = LogManager.GetLogger(typeof(AuthResHandler)); + + protected override void ChannelRead0(IChannelHandlerContext ctx, AuthRes msg) + { + int sn = (int)SessionMgr.GetAttrByKey(ctx.Channel.Id.ToString(), "charger_sn"); + Log.Info($"receive {msg} from {sn}"); + } + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Handler/Cmd106Handler.cs b/HybirdFrameworkServices/Charger/Handler/Cmd106Handler.cs deleted file mode 100644 index ccdec7e..0000000 --- a/HybirdFrameworkServices/Charger/Handler/Cmd106Handler.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DotNetty.Transport.Channels; -using HybirdFrameworkCore.Autofac.Attribute; -using HybirdFrameworkDriver.TcpServer; -using HybirdFrameworkServices.Charger.Msg; - -namespace HybirdFrameworkServices.Charger.Handler; - -[Order(9)] -[Scope("InstancePerDependency")] -public class Cmd106Handler : SimpleChannelInboundHandler, IMsgHandler -{ - protected override void ChannelRead0(IChannelHandlerContext ctx, Cmd106 msg) - { - } -} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Handler/IBaseHandler.cs b/HybirdFrameworkServices/Charger/Handler/IBaseHandler.cs new file mode 100644 index 0000000..69f8216 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Handler/IBaseHandler.cs @@ -0,0 +1,7 @@ +using DotNetty.Transport.Channels; + +namespace HybirdFrameworkServices.Charger.Handler; + +public interface IBaseHandler : IChannelHandler +{ +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Handler/IoSessionHandler.cs b/HybirdFrameworkServices/Charger/Handler/IoSessionHandler.cs deleted file mode 100644 index 91990bd..0000000 --- a/HybirdFrameworkServices/Charger/Handler/IoSessionHandler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using DotNetty.Transport.Channels; -using HybirdFrameworkCore.Autofac.Attribute; -using HybirdFrameworkDriver.TcpServer; - -namespace HybirdFrameworkServices.Charger.Handler; - -[Order(8)] -[Scope("InstancePerDependency")] -public class IoSessionHandler : SimpleChannelInboundHandler, IMsgHandler -{ - protected override void ChannelRead0(IChannelHandlerContext ctx, IoSession msg) - { - } -} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Handler/LoginHandler.cs b/HybirdFrameworkServices/Charger/Handler/LoginHandler.cs new file mode 100644 index 0000000..3b7e227 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Handler/LoginHandler.cs @@ -0,0 +1,42 @@ +using DotNetty.Transport.Channels; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkDriver.Session; +using HybirdFrameworkServices.Charger.Msg.Charger.Req; +using HybirdFrameworkServices.Charger.Msg.Host.Resp; +using log4net; + +namespace HybirdFrameworkServices.Charger.Handler +{ + /// + /// 3.3.3 充放电机登陆签到 + /// 监控平台应答充电设备登录签到报文 + /// + /// 1,保存日志到log + /// 2,回复签到应答 + /// 3,保存签到应答日志 + /// + /// + [Order(8)] + [Scope("InstancePerDependency")] + public class LoginHandler : SimpleChannelInboundHandler,IBaseHandler + { + private static readonly ILog Log = LogManager.GetLogger(typeof(LoginHandler)); + + protected override void ChannelRead0(IChannelHandlerContext ctx, Login msg) + { + msg.ConnProtocolVersion = msg.ConnProtocolVersion0 + "." + msg.ConnProtocolVersion1 + "." + + msg.ConnProtocolVersion2; + msg.ControllerHardwareVersion = msg.ControllerHardwareVersion0 + "." + msg.ControllerHardwareVersion1 + + "." + msg.ControllerHardwareVersion2; + msg.ControllerSoftwareVersion = msg.ControllerSoftwareVersion0 + "." + msg.ControllerSoftwareVersion1 + + "." + msg.ControllerSoftwareVersion2; + int sn = (int)SessionMgr.GetAttrByKey(ctx.Channel.Id.ToString(), "charger_sn"); + Log.Info($"receive {msg} from {sn}"); + + + LogSignMessage logSignMessage = new LogSignMessage(0); + logSignMessage.DestAddr = new byte[] { 0x01, 0x02, 0x03 }; + ctx.Channel.WriteAndFlushAsync(logSignMessage); + } + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Msg/APCI.cs b/HybirdFrameworkServices/Charger/Msg/APCI.cs new file mode 100644 index 0000000..514d299 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/APCI.cs @@ -0,0 +1,46 @@ +using HybirdFrameworkDriver.Common; +using HybirdFrameworkServices.Charger.Common; + +namespace HybirdFrameworkServices.Charger.Msg +{ + public abstract class APCI : IToBytes + { + /// + /// 报文长度 + /// + public UInt16 PackLen { get; set; } + + /// + /// 控制域 + /// + public UInt32 CtlArea { get; set; } + + /// + /// 目标地址 + /// + public byte[] DestAddr { get; set; } + + /// + /// 源地址 + /// + public UInt32 SrcAddr { get; set; } + + + public byte[] ToBytes() + { + byte[] bodyBytes = GetBytes(); + List list = new List(); + list.AddRange(ChargerConst.ApciStartChar); + list.AddRange(BitConverter.GetBytes(bodyBytes.Length + 12)); + list.AddRange(BitConverter.GetBytes(CtlArea)); + list.AddRange(DestAddr); + list.AddRange(BitConverter.GetBytes(SrcAddr)); + + list.AddRange(bodyBytes); + + return list.ToArray(); + } + + public abstract byte[] GetBytes(); + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Msg/ASDU.cs b/HybirdFrameworkServices/Charger/Msg/ASDU.cs new file mode 100644 index 0000000..55dfae0 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/ASDU.cs @@ -0,0 +1,75 @@ +using DotNetty.Buffers; +using HybirdFrameworkCore.Utils; +using HybirdFrameworkServices.Charger.Common; + +namespace HybirdFrameworkServices.Charger.Msg +{ + public class ASDU : APCI + { + /// + /// 帧类型号 + /// + public byte FrameTypeNo { get; set; } + + /// + /// 信息体个数 + /// + public byte MsgBodyCount { get; set; } + + /// + /// 传送原因-3.1.3.2 + /// + public UInt16 TransReason { get; set; } + + /// + /// 公共地址 + /// + public UInt16 PublicAddr { get; set; } + + /// + /// 信息体地址-3个字节 + /// + public byte[]? MsgBodyAddr { get; set; } + + + public override byte[] GetBytes() + { + List list = new List(); + list.Add(FrameTypeNo); + list.Add(MsgBodyCount); + list.AddRange(BitConverter.GetBytes(TransReason)); + list.AddRange(BitConverter.GetBytes(PublicAddr)); + list.AddRange(MsgBodyAddr); + + list.AddRange(ModelConvert.Encode(this)); + return list.ToArray(); + } + + + public static void ParseHeader(IByteBuffer byteBuffer, ASDU asdu) + { + int start = ChargerConst.ApciStartChar.Length - 1; + + asdu.PackLen = byteBuffer.GetUnsignedShortLE(start + 1); + asdu.CtlArea = byteBuffer.GetUnsignedInt(start + 3); + asdu.DestAddr = new[] + { + byteBuffer.GetByte(start + 7), + byteBuffer.GetByte(start + 8), + byteBuffer.GetByte(start + 9), + byteBuffer.GetByte(start + 10), + }; + asdu.SrcAddr = byteBuffer.GetUnsignedInt(start + 11); + asdu.FrameTypeNo = byteBuffer.GetByte(start + 15); + asdu.MsgBodyCount = byteBuffer.GetByte(start + 16); + asdu.TransReason = byteBuffer.GetUnsignedShortLE(start + 17); + asdu.PublicAddr = byteBuffer.GetUnsignedShortLE(start + 19); + asdu.MsgBodyAddr = new[] + { + byteBuffer.GetByte(start + 21), + byteBuffer.GetByte(start + 22), + byteBuffer.GetByte(start + 23), + }; + } + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Msg/Charger/Req/Login.cs b/HybirdFrameworkServices/Charger/Msg/Charger/Req/Login.cs new file mode 100644 index 0000000..d3ddbec --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/Charger/Req/Login.cs @@ -0,0 +1,88 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace HybirdFrameworkServices.Charger.Msg.Charger.Req +{ + /// + /// 3.3.3 充放电机登陆签到 + /// + public class Login : ASDU + { + /// + /// 记录类型 + /// + [Property(0, 8)] + public byte RecordType { get; set; } + /// + /// 监控网关编号 + /// + [Property(8, 16)] + public UInt16 GatewayNo { get; set; } + /// + /// 设备属性 + /// + [Property(24, 8)] + public byte EquipType { get; set; } + /// + /// 通讯协议版本 + /// + [Property(32, 8)] + public byte ConnProtocolVersion0 { get; set; } + [Property(40, 8)] + public byte ConnProtocolVersion1 { get; set; } + [Property(48, 8)] + public byte ConnProtocolVersion2 { get; set; } + public string ConnProtocolVersion { get; set; } + /// + /// 充电控制器硬件版本号 + /// + [Property(56, 8)] + public byte ControllerHardwareVersion0 { get; set; } + [Property(64, 8)] + public byte ControllerHardwareVersion1 { get; set; } + [Property(72, 8)] + public byte ControllerHardwareVersion2 { get; set; } + public string ControllerHardwareVersion { get; set; } + /// + /// 充电控制器软件版本 + /// + [Property(80, 8)] + public byte ControllerSoftwareVersion0 { get; set; } + [Property(88, 8)] + public byte ControllerSoftwareVersion1 { get; set; } + [Property(96, 8)] + public byte ControllerSoftwareVersion2 { get; set; } + public string ControllerSoftwareVersion { get; set; } + /// + /// 充电枪口数目 + /// + [Property(104, 8)] + public byte GunNum { get; set; } + /// + /// 充电模块数目 + /// + [Property(112, 8)] + public byte GunModuleNum { get; set; } + /// + /// 额定功率 + /// + [Property(128, 16)] + public ushort RatedPower { get; set; } + /// + /// 当前功率 + /// + [Property(136, 8)] + public byte CurrentPower { get; set; } + /// + /// 当前速率 + /// + [Property(144, 8)] + public byte CurrentSpeed { get; set; } + /// + /// 分流器量程 + /// + [Property(152, 16)] + public ushort DiverterRange { get; set; } + + + } +} diff --git a/HybirdFrameworkServices/Charger/Msg/Charger/Resp/AuthRes.cs b/HybirdFrameworkServices/Charger/Msg/Charger/Resp/AuthRes.cs new file mode 100644 index 0000000..f8ef764 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/Charger/Resp/AuthRes.cs @@ -0,0 +1,35 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace HybirdFrameworkServices.Charger.Msg.Charger.Resp +{ + /// + /// 3.3.2 充放电机应答鉴权认证 + /// + public class AuthRes : ASDU + + { + /// + /// 记录类型 + /// + [Property(0, 8)] + public byte RecordType { get; set; } + /// + /// 连接序号 + /// + [Property(8, 16)] + public ushort ConnSeq { get; set; } + + /// + /// 鉴权结果 + /// + [Property(24, 8)] + public byte AuthResult { get; set; } + + /// + /// 失败原因 + /// + [Property(32, 8)] + public byte FailReason { get; set; } + + } +} diff --git a/HybirdFrameworkServices/Charger/Msg/Cmd106.cs b/HybirdFrameworkServices/Charger/Msg/Cmd106.cs deleted file mode 100644 index c0f3ecd..0000000 --- a/HybirdFrameworkServices/Charger/Msg/Cmd106.cs +++ /dev/null @@ -1,9 +0,0 @@ -using HybirdFrameworkCore.Autofac.Attribute; - -namespace HybirdFrameworkServices.Charger.Msg; - -[Scope("InstancePerDependency")] -public class Cmd106 -{ - -} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Msg/Host/Req/Auth.cs b/HybirdFrameworkServices/Charger/Msg/Host/Req/Auth.cs new file mode 100644 index 0000000..b522b8f --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/Host/Req/Auth.cs @@ -0,0 +1,57 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace HybirdFrameworkServices.Charger.Msg.Host.Req +{ + /// + /// 3.3.1 监控平台鉴权认证 + /// + public class Auth : ASDU + { + /// + /// 记录类型 + /// + public byte RecordType { get; set; } + /// + /// 客户端类型.1站控 2本地控制器 3测试客户端 4TCU模式 0未知设备 + /// + [Property(0, 8)] + public byte ClientType { get; set; } + + /// + /// 连接序号 + /// + [Property(8, 16)] + public ushort ConnSeq { get; set; } + + /// + /// 鉴权码字节数组 + /// + [Property(24, 64)] + public byte[] AuthCodes { get; set; } + + /// + /// 鉴码KEY + /// + [Property(88, 8)] + public byte AuthCodeKey { get; set; } + + public Auth(ushort connseq, byte[] authcodes, byte authcodekey) + { + PackLen = 0; + CtlArea = 0; + SrcAddr = 0; + + FrameTypeNo = 45; + MsgBodyCount = 1; + TransReason = 3; + PublicAddr = 0; + MsgBodyAddr = new byte[] { 0, 0, 0 }; + + RecordType = 24; + ClientType = 1; + ConnSeq = connseq; + AuthCodes = authcodes; + AuthCodeKey = authcodekey; + } + } +} \ No newline at end of file diff --git a/HybirdFrameworkServices/Charger/Msg/Host/Resp/LogSignMessage.cs b/HybirdFrameworkServices/Charger/Msg/Host/Resp/LogSignMessage.cs new file mode 100644 index 0000000..5fe2b00 --- /dev/null +++ b/HybirdFrameworkServices/Charger/Msg/Host/Resp/LogSignMessage.cs @@ -0,0 +1,89 @@ +using HybirdFrameworkCore.Autofac.Attribute; + +namespace HybirdFrameworkServices.Charger.Msg.Host.Resp +{ + /// + /// 3.3.4 监控平台应答充电设备登录签到报文 + /// + public class LogSignMessage : ASDU + { + [Property(0, 8)] public byte RecordType { get; set; } + + /// + /// 结果 + /// 0:成功/确认 + ///1:失败-平台处理该消息失败 + ///2:消息有误-消息校验错误/消息长度有误 + ///4:该设备编码在系统没有找到 + ///5:该设备编码在系统中异常,可能存在冲突 + ///6:充电控制器数目不对 + ///255:其它错误 + /// + [Property(8, 8)] + public byte Result { get; set; } + + /// + /// 年 + /// + [Property(16, 16)] + public ushort TimeYear { get; set; } + + /// + /// 月 + /// + [Property(32, 8)] + public byte TimeMonth { get; set; } + + /// + /// 日 + /// + [Property(40, 8)] + public byte TimeDay { get; set; } + + /// + /// 时 + /// + [Property(48, 8)] + public byte TimeHour { get; set; } + + /// + /// 分 + /// + [Property(56, 8)] + public byte TimeMinute { get; set; } + + /// + /// 秒 + /// + [Property(64, 8)] + public byte TimeSecond { get; set; } + + /// + /// 保留:1位, 默认0xFF + /// + [Property(72, 8)] + public byte Time { get; set; } + + public LogSignMessage(byte result) + { + Result = result; + + CtlArea = 0; + SrcAddr = 0; + FrameTypeNo = 45; + MsgBodyCount = 1; + TransReason = 4; + PublicAddr = 0; + MsgBodyAddr = new byte[] { 0, 0, 0 }; + RecordType = 12; + + DateTime dtime = DateTime.Now; + TimeYear = Convert.ToUInt16(dtime.Year.ToString()); + TimeMonth = Convert.ToByte(dtime.Month); + TimeDay = Convert.ToByte(dtime.Day); + TimeHour = Convert.ToByte(dtime.Hour); + TimeMinute = Convert.ToByte(dtime.Minute); + TimeSecond = Convert.ToByte(dtime.Second); + } + } +} \ No newline at end of file diff --git a/WebStarter/Program.cs b/WebStarter/Program.cs index 5fe1276..8e62897 100644 --- a/WebStarter/Program.cs +++ b/WebStarter/Program.cs @@ -65,7 +65,4 @@ app.MapControllers(); AppInfo.Container = app.Services.GetAutofacRoot(); -Server server = AppInfo.Container.Resolve(); -server.Start(9000); - app.Run(); \ No newline at end of file diff --git a/WinFormStarter/Form2.cs b/WinFormStarter/Form2.cs index 317e02a..ef85d94 100644 --- a/WinFormStarter/Form2.cs +++ b/WinFormStarter/Form2.cs @@ -1,15 +1,9 @@ -using HybirdFrameworkDriver.TcpServer; - -namespace WinFormStarter; +namespace WinFormStarter; public partial class Form2 : Form { - - private Server _server; - public Form2(Server server) + public Form2() { - _server = server; InitializeComponent(); - _server.Start(9000); } } \ No newline at end of file diff --git a/WinFormStarter/bin/Debug/net6.0-windows/Microsoft.Extensions.Logging.Abstractions.dll b/WinFormStarter/bin/Debug/net6.0-windows/Microsoft.Extensions.Logging.Abstractions.dll index 2c87f79..bb27a2f 100644 Binary files a/WinFormStarter/bin/Debug/net6.0-windows/Microsoft.Extensions.Logging.Abstractions.dll and b/WinFormStarter/bin/Debug/net6.0-windows/Microsoft.Extensions.Logging.Abstractions.dll differ