DotNetty使用之心跳机制

DotNetty使用之心跳机制因为 DotNetty 是从 java 的 Netty 框架仿写过来的 介绍的文档特别少 加之官方也没有提供 api 文档 所以之前一直不理解心跳的用法 最近忙里偷闲 稍稍研究了一番 终于有点明白了 现在将代码复制上来 留作日后查看 ps 精髓都在代码里 Uptime Client publicclassP conststringH 12

因为DotNetty是从java的Netty框架仿写过来的,介绍的文档特别少,加之官方也没有提供api文档,所以之前一直不理解心跳的用法。最近忙里偷闲,稍稍研究了一番,终于有点明白了。

现在将代码复制上来,留作日后查看(ps:精髓都在代码里):

Uptime.Client:

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);//第一个参数为读,第二个为写,第三个为读写全部 })); } }

Uptime.Client.UptimeClientHandler:

 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); } }

Uptime.Server:

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))); } } }

Uptime.Server.UptimeServerHandler:

 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心跳机制,群发

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232262.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C#的继承_继承关系中的被继承人

    C#的继承_继承关系中的被继承人继承详解:一.继承的概念:二.基类和派生类:三.继承的作用:四.继承的特点:五.举例说明:六.继承注意事项:一.继承的概念:继承:是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。当创建一个类时,不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类/父类,这个新的类被称为派生类/子类。二.基类和派生类:基类/父类:也可以理解成生活中的父亲

    2025年10月15日
    3
  • Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题

    Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题Delphixe5控件TIdhttp的用法post,get解决中文乱码问题

    2022年7月18日
    17
  • PSCU选择Qlik支持其完善的服务交付战略「建议收藏」

    PSCU选择Qlik支持其完善的服务交付战略

    2022年4月2日
    79
  • 万字图解Java多线程

    万字图解Java多线程前言java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程api的应用场景,不知道多线程的运行流程等等,本篇文章将使用实例+图解+源码的方式来解析java多线程。文章篇幅较长,大家也可以有选择的看具体章节,建议多线程的代码全部手敲,永远不要相信你看到的结论,自己编码后运行出来的,才是自己的。什么是java多线程?进程与线程进程当一个程序被运行,就开启了一个进程,比如启动了qq,w.

    2022年6月6日
    35
  • WebStorm 7.0 注冊码

    WebStorm 7.0 注冊码

    2021年12月4日
    46
  • 个人项目 Individual Project

    个人项目 Individual Project

    2021年11月18日
    57

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号