You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Concurrent;
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 log4net;
using Module.Socket.Tool;
namespace HybirdFrameworkServices.Netty
{
/// <summary>
/// netty server
/// </summary>
public class Server : IDisposable
{
private readonly ILog Log = LogManager.GetLogger(typeof(Server));
/// <summary>
/// 接受客户端的连接
/// </summary>
static MultithreadEventLoopGroup? bossGroup;
/// <summary>
/// 处理已经被接受的连接
/// </summary>
static MultithreadEventLoopGroup? workerGroup;
/// <summary>
/// Netty服务器的启动辅助类用于配置和启动服务器
/// </summary>
static ServerBootstrap? bootstrap;
/// <summary>
/// 是一个线程安全的字典用于存储与客户端连接的通道IChannel
/// </summary>
static ConcurrentDictionary<IChannelId, IChannel> _container = ServerListenerHandler.Container;
private int _port = 9000;
public Server(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<TcpServerSocketChannel>() // 设置通道模式为TcpSocket
.Option(ChannelOption.SoKeepalive, true) //设置TCP连接socket,保持连接
.Handler(new LoggingHandler())//添加log处理日志
.ChildHandler(new ActionChannelInitializer<ISocketChannel>(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 CustomFrameDecoder4(new IByteBuffer[] { delimiter }, false, false));
pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时
//pipeline.AddLast(new ReconnectHandler(this));
//pipeline.AddLast(new ClientHandler(this));
}));
Begin(_port);
}
private void Begin(int port)
{
_port = port;
Log.Info(" Start Listen");
Task<IChannel>? channel = bootstrap?.BindAsync(_port);
Log.Info($"netty success listen {_port}");
}
public static void Send(byte[] bytes)
{
foreach (IChannel channel in _container.Values)
{
channel.WriteAndFlushAsync(bytes);
}
}
/// <summary>
/// ??netty 释放资源
/// </summary>
public void Dispose()
{
Log.Info(this + " Dispose");
bossGroup?.ShutdownGracefullyAsync();
}
}
}