Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说netty 心跳机制_dubbo心跳机制,希望能够帮助你!!!。
因为DotNetty是从java的Netty框架仿写过来的,介绍的文档特别少,加之官方也没有提供api文档,所以之前一直不理解心跳的用法。最近忙里偷闲,稍稍研究了一番,终于有点明白了。
现在将代码复制上来,留作日后查看(ps:精髓都在代码里):
public class Program
{
const string HOST = "127.0.0.1";
const int PORT = 8045;
// Sleep 5 seconds before a reconnection attempt.
public const int RECONNECT_DELAY = 5;
// Reconnect when the server sends nothing for 10 seconds.
private const int READ_TIMEOUT = 10;
private static UptimeClientHandler handler = new UptimeClientHandler();
private static Bootstrap bs = new Bootstrap();
static void Main(string[] args)
{
EventLoopGroup group = new EventLoopGroup();
bs.Group(group)
.Channel<TcpSocketChannel>()
.RemoteAddress(HOST, PORT)
.Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
{
//IdleStateHandler心跳检测处理器,添加自定义处理Handler类实现userEventTriggered()方法作为超时事件的逻辑处理
//IdleStateHandler心跳检测每十秒进行一次读检测,如果十秒内ChannelRead()方法未被调用则触发一次userEventTrigger()方法.
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler);//第一个参数为读,第二个为写,第三个为读写全部
}));
}
}
public class UptimeClientHandler : SimpleChannelInboundHandler<object>
{
long startTime = -1;
//ChannelActive:活跃状态,可接收和发送数据
public override void ChannelActive(IChannelHandlerContext ctx)
{
if (startTime < 0)
{
startTime = GetTimeStamp();
}
Console.WriteLine("Connected to: " + ctx.Channel.RemoteAddress);
}
protected override void ChannelRead0(IChannelHandlerContext context, object message)
{
var byteBuffer = message as IByteBuffer;
if (byteBuffer != null)
{
Console.WriteLine("Received from server: " + byteBuffer.ToString(Encoding.UTF8));
}
context.WriteAsync(message);
}
public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
{
if (!(evt is IdleStateEvent))
{
return;
}
IdleStateEvent e = evt as IdleStateEvent;
if (e.State == IdleState.ReaderIdle)
{
// The connection was OK but there was no traffic for last period.
Console.WriteLine("Disconnecting due to no inbound traffic");
ctx.CloseAsync();
}
}
//channelInactive: 处于非活跃状态,没有连接到远程主机。
public override void ChannelInactive(IChannelHandlerContext context)
{
Console.WriteLine("Disconnected from: " + context.Channel.RemoteAddress);
}
//channelUnregistered: 已创建但未注册到一个 EventLoop。
public override void ChannelUnregistered(IChannelHandlerContext context)
{
}
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
Console.WriteLine("Exception: " + exception);
context.CloseAsync();
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
private long GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalMilliseconds);
}
}
class Program
{
private static readonly int PORT = 8045;
private static readonly UptimeServerHandler handler = new UptimeServerHandler();
static void Main(string[] args) => RunServerAsync().Wait();
static async Task RunServerAsync()
{
IEventLoopGroup bossGroup = new MultithreadEventLoopGroup(1);
IEventLoopGroup workerGroup = new MultithreadEventLoopGroup();
try
{
ServerBootstrap b = new ServerBootstrap();
b.Group(bossGroup, workerGroup)
.Channel<TcpServerSocketChannel>()
.Handler(new LoggingHandler("SRV-LSTN"))
.ChildHandler(new ActionChannelInitializer<IChannel>(channel =>
{
//工作线程连接器 是设置了一个管道,服务端主线程所有接收到的信息都会通过这个管道一层层往下传输
//同时所有出栈的消息也要这个管道的所有处理器进行一步步处理
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast("Uptime", handler);
}));
// Bind and start to accept incoming connections.
IChannel boundChannel = await b.BindAsync(PORT);
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
await boundChannel.CloseAsync();
}
finally
{
await Task.WhenAll(
bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),
workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
}
}
}
public class UptimeServerHandler : SimpleChannelInboundHandler<object> {
protected override void ChannelRead0(IChannelHandlerContext ctx, object msg)
{
// discard
}
//捕获 异常,并输出到控制台后断开链接,提示:客户端意外断开链接,也会触发
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
Console.WriteLine("Exception: " + exception);
context.CloseAsync();
}
}
最后,附上参考文档链接:DotNetty系列三:编码解码器,IdleStateHandler心跳机制,群发
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章