using Abp.Dependency; using DotNetty.Buffers; using DotNetty.Codecs; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using Serilog; using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime; using System.Threading.Tasks; using Yunda.SOMS.OperationsMainSiteGatewayServer.TcpSocket.TestData; namespace Yunda.SOMS.OperationsMainSiteGatewayServer.TcpSocket.Server { public class DotNettyTcpServer : ISingletonDependency { // 定义 MessageReceived 事件 public event Action< byte, byte[], byte> MessageReceived; // 装置地址,功能码,消息 public Dictionary dotNettyServerHandlers = new Dictionary(); public DotNettyTcpServer() { //_dotNettyServerHandler = dotNettyServerHandler; MessageReceived += DotNettyTcpServer_MessageReceived; } private async void DotNettyTcpServer_MessageReceived(byte addr, byte[] data, byte functype) { if (functype == 10) //总召 { SimulateData.Test1(this); await Task.Delay(1000); SimulateData.Test2(this); await Task.Delay(1000); SimulateData.Test3(this); await Task.Delay(1000); SimulateData.Test4(this); await Task.Delay(1000); } } MultithreadEventLoopGroup bossGroup ; MultithreadEventLoopGroup workerGroup ; int maxFrameLength = 65536; // 设置最大帧长度 int lengthFieldOffset = 1; // 长度字段的偏移量,从启动字符之后开始 int lengthFieldLength = 2; // 长度字段的字节长度 int lengthAdjustment = -3; // 长度调整,将读取的长度减去启动字符和长度字段的字节数 int initialBytesToStrip = 0; // 保留所有字节 public async Task RunServerAsync(byte addr) { bossGroup = new MultithreadEventLoopGroup(1); workerGroup = new MultithreadEventLoopGroup(); try { GCSettings.LatencyMode = GCLatencyMode.LowLatency; var bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup) .Channel() .Option(ChannelOption.SoBacklog, 100) .ChildHandler(new ActionChannelInitializer(channel => { var serverHandler = new DotNettyServerHandler(MessageReceived, OnChannelInactive, addr); channel.Pipeline.AddLast(new LengthFieldBasedFrameDecoder( maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip )); channel.Pipeline.AddLast(serverHandler); channel.Pipeline.AddLast("hexDumpHandler", new HexDumpHandler()); string ip = channel.RemoteAddress.ToString(); if (!dotNettyServerHandlers.ContainsKey(ip)) { dotNettyServerHandlers.Add(ip, serverHandler); } else { dotNettyServerHandlers[ip] = serverHandler; } })); IChannel boundChannel = await bootstrap.BindAsync(3000); Log.Information("服务器启动并监听端口 3000..."); } finally { } } // 客户端断开连接时的回调 private void OnChannelInactive(string channelIp) { Console.WriteLine($"客户端断开连接: {channelIp}"); dotNettyServerHandlers.Remove(channelIp); } public async Task StopSeverAsync() { try { await Task.WhenAll( bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)), workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1))); } catch (Exception ex) { Log.Information("服务器关闭并监听端口 7110...", "获取信息"); } } public async void SendMessage(byte address, byte functionType, string data) { try { foreach (var item in dotNettyServerHandlers.Values) { //byte addr = byte(new Random().Next(1,99)); byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(data); await item.SendCustomMessageAsync(address, functionType, utf8Bytes); } } catch (Exception ex) { Log.Error(ex,""); } } } }