|
|
|
@ -13,54 +13,59 @@ using HybirdFrameworkCore.Autofac;
|
|
|
|
|
using HybirdFrameworkCore.Autofac.Attribute;
|
|
|
|
|
using log4net;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using LogLevel = DotNetty.Handlers.Logging.LogLevel;
|
|
|
|
|
|
|
|
|
|
namespace HybirdFrameworkDriver.TcpClient;
|
|
|
|
|
|
|
|
|
|
public class TcpClient<TH, TD, TE> where TH : IChannelHandler
|
|
|
|
|
public class TcpClient<TH, TD, TE> : IDisposable where TH : IChannelHandler
|
|
|
|
|
where TD : ByteToMessageDecoder, new()
|
|
|
|
|
where TE : ChannelHandlerAdapter, new()
|
|
|
|
|
{
|
|
|
|
|
[JsonIgnore]
|
|
|
|
|
private static readonly ILog Log = LogManager.GetLogger(typeof(TcpClient<TH, TD, TE>));
|
|
|
|
|
|
|
|
|
|
[JsonIgnore]
|
|
|
|
|
private Bootstrap? _bootstrap;
|
|
|
|
|
|
|
|
|
|
public IChannel Channel { get; set; }
|
|
|
|
|
[JsonIgnore]
|
|
|
|
|
private IEventLoopGroup? _eventLoopGroup;
|
|
|
|
|
[JsonIgnore]
|
|
|
|
|
public IChannel? Channel { get; set; }
|
|
|
|
|
|
|
|
|
|
public bool Connected { get; set; }
|
|
|
|
|
|
|
|
|
|
public string Host { get; set; }
|
|
|
|
|
public int Port { get; set; }
|
|
|
|
|
|
|
|
|
|
public bool AutoReconnect { get; set; }
|
|
|
|
|
public LogLevel? LogLevel { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void InitBootstrap(string host, int port, Action? channelInactiveHandler = null)
|
|
|
|
|
{
|
|
|
|
|
Host = host;
|
|
|
|
|
Port = port;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (LogLevel != null)
|
|
|
|
|
{
|
|
|
|
|
InternalLoggerFactory.DefaultFactory.AddProvider(new Log4NetProvider());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bootstrap = new Bootstrap();
|
|
|
|
|
_eventLoopGroup = new MultithreadEventLoopGroup();
|
|
|
|
|
_bootstrap
|
|
|
|
|
.Group(new MultithreadEventLoopGroup())
|
|
|
|
|
.Group(_eventLoopGroup)
|
|
|
|
|
.Channel<TcpSocketChannel>()
|
|
|
|
|
.Option(ChannelOption.TcpNodelay, true)
|
|
|
|
|
.Handler(new LoggingHandler())
|
|
|
|
|
.Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
|
|
|
|
|
{
|
|
|
|
|
var clientListenerHandler = new ClientListenerHandler<TH, TD, TE>(this);
|
|
|
|
|
var clientListenerHandler = new ClientListenerHandler<TH, TD, TE>(this, AutoReconnect);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pipeline = channel.Pipeline;
|
|
|
|
|
|
|
|
|
|
if (LogLevel != null)
|
|
|
|
|
{
|
|
|
|
|
pipeline.AddLast(new LoggingHandler(LogLevel.Value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 监听器
|
|
|
|
|
pipeline.AddLast(clientListenerHandler);
|
|
|
|
|
pipeline.AddLast("idleStateHandler", new IdleStateHandler(30, 0, 0)); // 触发读取超时
|
|
|
|
@ -125,12 +130,12 @@ public class TcpClient<TH, TD, TE> where TH : IChannelHandler
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Connect()
|
|
|
|
|
public void BaseConnect()
|
|
|
|
|
{
|
|
|
|
|
Connected = false;
|
|
|
|
|
Log.Info($"begin to connect {Host}:{Port}");
|
|
|
|
|
|
|
|
|
|
while (Connected)
|
|
|
|
|
while (!Connected)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
@ -147,4 +152,17 @@ public class TcpClient<TH, TD, TE> where TH : IChannelHandler
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
this.Channel?.CloseAsync().Wait();
|
|
|
|
|
this.Channel?.CloseCompletion.Wait();
|
|
|
|
|
_eventLoopGroup?.ShutdownGracefullyAsync().Wait();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
this.Close();
|
|
|
|
|
this.Connected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|