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,string id)
{
foreach (IChannel channel in _container.Values)
{
channel.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();
}
}
}
}