using System.Reflection;
using Autofac;
using Autofac.Core;
using DotNetty.Codecs;
using DotNetty.Handlers.Logging;
using DotNetty.Handlers.Timeout;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
namespace HybirdFrameworkDriver.TcpServer
{
///
/// netty server
///
public class TcpServer
: IDisposable where TH : IChannelHandler where TD: ByteToMessageDecoder,new() where TE: ChannelHandlerAdapter, new()
{
private static readonly ILog Log = LogManager.GetLogger(typeof(TcpServer | ));
static MultithreadEventLoopGroup? bossGroup;
static MultithreadEventLoopGroup? workerGroup;
static ServerBootstrap? bootstrap;
private int _port = 9000;
public TcpServer()
{
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 IdleStateHandler(0, 0, 180)); //检测空闲连接
//业务handler ,这里是实际处理业务的Handler
ResolveEncode(pipeline);
ResolveDecode(pipeline);
ResolveHandler(pipeline);
}));
}
private void ResolveEncode(IChannelPipeline pipeline)
{
pipeline.AddLast(new TE());
}
private void ResolveDecode(IChannelPipeline pipeline)
{
pipeline.AddLast(new TD());
}
private void ResolveHandler(IChannelPipeline pipeline)
{
List list = new List();
foreach (IComponentRegistration reg in AppInfo.Container.ComponentRegistry.Registrations)
{
foreach (Service service in reg.Services)
{
if (service is TypedService ts)
{
if (MatchHandlers(ts))
{
list.Add(ts.ServiceType);
}
}
}
}
List handlers = new List | ();
foreach (var type in list)
{
object resolve = AppInfo.Container.Resolve(type);
handlers.Add((TH) resolve);
}
handlers.Sort((handler, msgHandler) =>
{
OrderAttribute? orderAttribute1 = handler.GetType().GetCustomAttribute();
OrderAttribute? orderAttribute2 = msgHandler.GetType().GetCustomAttribute();
int h1Order = orderAttribute1?.Order ?? 0;
int h2Order = orderAttribute2?.Order ?? 0;
return h1Order.CompareTo(h2Order);
});
foreach (var msgHandler in handlers)
{
pipeline.AddLast((IChannelHandler)msgHandler);
}
}
private bool MatchHandlers(TypedService ts)
{
Type[] interfaces = ts.ServiceType.GetInterfaces();
if (interfaces.Length > 0)
{
foreach (Type type in interfaces)
{
if (type == typeof(TH))
{
return true;
}
}
}
return false;
}
public void Start(int port)
{
_port = port;
Log.Info(" Start Listen");
Task? channel = bootstrap?.BindAsync(_port);
Log.Info($"netty success listen {_port}");
}
///
/// ??netty
///
public void Dispose()
{
Log.Info(this + " Dispose");
bossGroup?.ShutdownGracefullyAsync();
}
}
} | | |