• 基于Netty的程序主动发送消息


    开发中希望基于netty开发的客户端可以既能在启动时与服务器通讯,又能在指定时间点或事件与服务器通讯,比如主动发送注销信息。

    1. 在启动时与服务器通讯可以在ChannelHandler的channleActive方法中实现。当客户端与服务端TCP链路建立成功时,Netty的NIO线程会调用channleActive方法,其中可以通过入参ChannelHandlerContext 的writeAndFlush方法发送指令给服务器。这一步是ChannelHandler 添加到ChannelPipeline 之后自动触发并接入ChannelHandlerContext参数的。

    2. 在指定时间点或事件与服务器通讯时,在函数里依然需要ChannelHandlerContext来发送指令,虽然没有程序可以传入该参数,但我们实际可以缓存ChannelHandlerContext,并直接使用。

    ChannelHandlerContext是在ChannelHandler 添加到 ChannelPipeline 时创建的一个实例,它代表了 ChannelHandler 和ChannelPipeline 之间的关联。接口ChannelHandlerContext 主要是对通过同一个 ChannelPipeline 关联的 ChannelHandler 之间的交互进行管理。ChannelHandlerContext 与 ChannelHandler 的关联从不改变,所以缓存它的引用是安全的。

    可以通过重写handlerAdded函数,缓存ChannelHandlerContext的引用。该函数在ChannelHandler 添加到 ChannelPipeline 时触发。

    代码如下

    public class ClientHandlerDemo extends ChannelDuplexHandler   {
        /**缓存ChannelHandlerContext*/
        private ChannelHandlerContext ctx;
        
        @Override
        /*添加到pipeline时自动触发*/
        public void handlerAdded(ChannelHandlerContext ctx) {
            this.ctx = ctx;
        }
        
        /**
         * 建立连接时
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            logger.info("尝试建立连接时间:" + new Date());
            ctx.writeAndFlush(buildLogonMessage());
        }
        
        /**
         * 关闭连接时
         */
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            logger.info("Handler关闭连接。");
            super.channelInactive(ctx);
        }
    
        @Override
        public void close(ChannelHandlerContext ctx, ChannelPromise future) throws Exception {
            logger.info("Handler关闭连接处理,时间:" + new Date());
            super.close(ctx, future);
        }
        
        /**主动关闭连接*/
        public void toClose() {
            if(ctx == null ) {
                logger.info("未建立连接。");
                return;
            }
            logger.info("发送注销消息,主动关闭连接。");
            ctx.channel().writeAndFlush(buildLogoutMessage()).addListener(ChannelFutureListener.CLOSE);
        }
    }

    参考

    https://www.w3cschool.cn/essential_netty_in_action/essential_netty_in_action-bj5a28bq.html

  • 相关阅读:
    videojs 隐藏videobar
    nw 系统托盘的添加方式,以及ajax失效问题
    nw 注册快捷键
    bg-script 错误信息显示,以及global
    input 文件上传
    git stash,git cherry-pick
    安装Laravel
    nw + iframe嵌入page 滚动条问题
    require('nw.gui') 失效问题
    dell 交换机 双链路冗余
  • 原文地址:https://www.cnblogs.com/zhaoshizi/p/13817496.html
Copyright © 2020-2023  润新知