using System.Collections.Concurrent; using System.Net; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using System.Threading.Channels; using DotNetty.Buffers; using DotNetty.Handlers.Logging; using DotNetty.Handlers.Timeout; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkServices.System; using log4net; namespace HybirdFrameworkServices.Netty { /// /// netty server /// [Scope("SingleInstance")] public class Server : IDisposable { private readonly ILog Log = LogManager.GetLogger(typeof(Server)); static MultithreadEventLoopGroup? bossGroup; static MultithreadEventLoopGroup? workerGroup; static ServerBootstrap? bootstrap; static ConcurrentDictionary _container = ServerListenerHandler.Container; private int _port = 9000; public void connect(int port) { _port = port; IByteBuffer delimiter = Unpooled.CopiedBuffer(new byte[] { 0xAA, 0xF5 }); bossGroup = new MultithreadEventLoopGroup(); workerGroup = new MultithreadEventLoopGroup(); bootstrap = new ServerBootstrap(); bootstrap .Group(bossGroup, workerGroup) // 设置主和工作线程组 .Channel() // 设置通道模式为TcpSocket .Option(ChannelOption.SoKeepalive, true) //保持连接 .Handler(new LoggingHandler()) .ChildHandler(new ActionChannelInitializer(channel => { var serverListenerHandler = new ServerListenerHandler(); IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LoggingHandler("")); pipeline.AddLast(serverListenerHandler); //pipeline.AddLast(new FixedLengthFrameDecoder(12)); //定长数据,12byte pipeline.AddLast(new IdleStateHandler(0, 0, 180));//检测空闲连接 //pipeline.AddLast(msgHandler); //业务handler ,这里是实际处理业务的Handler pipeline.AddLast(new CustomFrameDecoder(new IByteBuffer[] { delimiter }, false, false)); pipeline.AddLast(new CustomFrameEncoder()); //// 添加客户端连接监控Handler pipeline.AddLast(new ClientConnectionMonitorHandler()); //pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时 //pipeline.AddLast(new ReconnectHandler(this)); //pipeline.AddLast(new ClientHandler(this)); })); Begin(_port); } public void Begin(int port) { _port = port; Log.Info(" Start Listen"); Task? channel = bootstrap?.BindAsync(_port); Log.Info($"netty success listen {_port}"); } public void Send(byte[] bytes) { foreach (IChannel channel in _container.Values) { channel.WriteAndFlushAsync(bytes); } } public void Send(byte[] bytes, IChannelId id) { //foreach (IChannel channel in _container.Values) //{ // channel.WriteAndFlushAsync(bytes); //} if (_container.ContainsKey(id)) _container[id].WriteAndFlushAsync(bytes); } /// /// ??netty /// public void Dispose() { Log.Info(this + " Dispose"); bossGroup?.ShutdownGracefullyAsync(); } /// /// 断开连接 /// public void Disconnect(string ip) { Log.Info(this + " Disconnect"); foreach (IChannel channel in _container.Values) { string input = 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; if (ip == ipAddress) channel.DisconnectAsync(); } } } }