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.

104 lines
3.7 KiB

8 months ago
using System.Reflection;
using Autofac;
using DotNetty.Codecs;
8 months ago
using DotNetty.Handlers.Logging;
using DotNetty.Handlers.Timeout;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
8 months ago
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkCore.Autofac.Attribute;
8 months ago
using log4net;
7 months ago
namespace HybirdFrameworkDriver.TcpServer
8 months ago
{
/// <summary>
/// netty server
/// </summary>
8 months ago
[Scope("InstancePerDependency")]
8 months ago
public class Server : IDisposable
{
private readonly ILog Log = LogManager.GetLogger(typeof(Server));
static MultithreadEventLoopGroup? bossGroup;
static MultithreadEventLoopGroup? workerGroup;
static ServerBootstrap? bootstrap;
private int _port = 9000;
8 months ago
public Server()
8 months ago
{
bossGroup = new MultithreadEventLoopGroup();
workerGroup = new MultithreadEventLoopGroup();
bootstrap = new ServerBootstrap();
bootstrap
.Group(bossGroup, workerGroup) // 设置主和工作线程组
.Channel<TcpServerSocketChannel>() // 设置通道模式为TcpSocket
.Option(ChannelOption.SoKeepalive, true) //保持连接
.Handler(new LoggingHandler())
.ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
{
var serverListenerHandler = new ServerListenerHandler();
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast(new LoggingHandler(""));
pipeline.AddLast(serverListenerHandler);
8 months ago
pipeline.AddLast(new IdleStateHandler(0, 0, 180)); //检测空闲连接
//业务handler 这里是实际处理业务的Handler
8 months ago
ResolveEncode(pipeline);
ResolveDecode(pipeline);
ResolveHandler(pipeline);
8 months ago
}));
}
8 months ago
private void ResolveEncode(IChannelPipeline pipeline)
{
IEncoder resolve = AppInfo.Container.Resolve<IEncoder>();
pipeline.AddLast((MessageToByteEncoder<byte[]>)resolve);
}
private void ResolveDecode(IChannelPipeline pipeline)
{
IDecoder resolve = AppInfo.Container.Resolve<IDecoder>();
pipeline.AddLast((ByteToMessageDecoder)resolve);
}
private void ResolveHandler(IChannelPipeline pipeline)
{
IEnumerable<IMsgHandler> handlers = AppInfo.Container.Resolve<IEnumerable<IMsgHandler>>();
IMsgHandler[] msgHandlers = handlers.ToArray();
Array.Sort(msgHandlers, (handler, msgHandler) =>
{
OrderAttribute? orderAttribute1 = handler.GetType().GetCustomAttribute<OrderAttribute>();
OrderAttribute? orderAttribute2 = msgHandler.GetType().GetCustomAttribute<OrderAttribute>();
int h1Order = orderAttribute1?.Order ?? 0;
int h2Order = orderAttribute2?.Order ?? 0;
return h1Order.CompareTo(h2Order);
});
foreach (var msgHandler in msgHandlers)
{
pipeline.AddLast((ChannelHandlerAdapter)msgHandler);
}
}
8 months ago
8 months ago
public void Start(int port)
8 months ago
{
_port = port;
Log.Info(" Start Listen");
Task<IChannel>? channel = bootstrap?.BindAsync(_port);
Log.Info($"netty success listen {_port}");
}
/// <summary>
/// ??netty
/// </summary>
public void Dispose()
{
Log.Info(this + " Dispose");
bossGroup?.ShutdownGracefullyAsync();
}
}
8 months ago
}