学习Netty的第三天


本章内容是观看《netty实战》书籍前7章,并且在B站重新找了一个学习视频,然后在观看部分课程后整理的。

不足之处

boosGroup 相当于一个组长
workerGroup相当于手下的员工
boosGroup将连接成功的通道分配给workerGroup

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
…………
serverBootstrap.group(bossGroup,workerGroup)
   .channel(NioServerSocketChannel.class)
   .option(ChannelOption.SO_BACKLOG,128)//分配任务队列
   .childOption(ChannelOption.SO_KEEPALIVE,true)
   .handler(new LoggingHandler(LogLevel.INFO))// bossGroup 增加日志处理器

聊天室

服务器配置类

 public class ChatServer {

   private int port;

   public ChatServer(int port) {
       this.port = port;
   }

   public void run() throws InterruptedException {

       EventLoopGroup bossGroup = new NioEventLoopGroup(1);
       EventLoopGroup workerGroup = new NioEventLoopGroup();
       try {


           ServerBootstrap serverBootstrap = new ServerBootstrap();

           serverBootstrap.group(bossGroup,workerGroup)
                   .channel(NioServerSocketChannel.class)
                   .option(ChannelOption.SO_BACKLOG,128)
                   .childOption(ChannelOption.SO_KEEPALIVE,true)
                   .handler(new LoggingHandler(LogLevel.INFO))// bossGroup 增加日志处理器
                   .childHandler(new ChannelInitializer<SocketChannel>() {
                       @Override
                       protected void initChannel(SocketChannel ch) throws Exception {
                           ChannelPipeline pipeline = ch.pipeline();
                           pipeline.addLast("decoder",new StringDecoder());//解码器
                           pipeline.addLast("encoder",new StringEncoder());//编码器
                           //当满足该条件后,会传递个下一个handler   在userEventTiggered方法中处理
                           pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));
                           pipeline.addLast("myServerHandler",new ChatServerHandler());

                       }
                   });
           ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
           System.out.println("服务器启动完成");
           channelFuture.channel().closeFuture().sync();

       } finally {
           bossGroup.shutdownGracefully();
           workerGroup.shutdownGracefully();
       }

   }

   public static void main(String[] args) throws InterruptedException {
       new ChatServer(6888).run();
   }
}

服务器处理类

public class ChatServerHandler extends SimpleChannelInboundHandler<String> {

    //GlobalEventExecutor.INSTANCE 全局事件执行器 单例
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //一旦连接  第一个被执行
    //将当前channel 加入到组中
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //底层自动循环
        channelGroup.writeAndFlush("客户端:" + channel.remoteAddress() + "加入聊天\n");
        channelGroup.add(channel);
    }

    //断开连接
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //channelGroup.remove(channel) 当触发handlerRemoved 会自动去除当前channel
        channelGroup.writeAndFlush("客户端:" + channel.remoteAddress() + "离开聊天\n");

    }

    //表示channel处于活动状态
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "在"+simpleDateFormat.format(new Date())+"上线了\n");
    }

    //表示channel不处于活动状态
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "在"+simpleDateFormat.format(new Date())+"离线了\n");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        final Channel channel = ctx.channel();
        //根据不同身份 发送信息(自己)
        channelGroup.forEach(ch -> {
            if (channel != ch) {//不是当前的通道
                ch.writeAndFlush("[客户]" + channel.remoteAddress() + "在"+simpleDateFormat.format(new Date())+"发送信息:" + msg+"\n");
            }else{
                ch.writeAndFlush("[自己]在"+simpleDateFormat.format(new Date())+"发送了消息:"+msg+"\n");
            }
        });

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        cause.printStackTrace();
    }

    /**
     * @Date: 2020/10/28 4:43 下午
     * @Param: evt 事件
     * @Param: ctx 上下文
     * @Author: Lmy
     * @Description:
    */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType=null;
            switch (event.state()){
                case READER_IDLE:
                    eventType="读空闲";
                    break;
                case WRITER_IDLE:
                    eventType="写空闲";
                    break;
                case ALL_IDLE:
                    eventType="读写空闲";
                    break;
            }
            System.out.println(ctx.channel().remoteAddress()+"-->超时事件发生:"+eventType);
        }
    }
}

客户端

客户端配置类


    private final String host;
    private final int prot;

    public ChatClient(String host, int prot) {
        this.host = host;
        this.prot = prot;
    }

    private void run() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap()
                    .group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast("encoder",new StringEncoder());
                            pipeline.addLast("decoder",new StringDecoder());
                            pipeline.addLast("myHandler",new ChatClientHandler());
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect(host, prot).sync();

            Channel channel = channelFuture.channel();
            System.out.println("————"+channel.localAddress()+"————");

            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNextLine()){
                String msg = scanner.nextLine();
                channel.writeAndFlush(msg+"\r\n");
            }
        } finally {
            group.shutdownGracefully();
        }

    }

    public static void main(String[] args) throws InterruptedException {
        new ChatClient("127.0.0.1",6888).run();
    } 

客户端处理类

@Override
 protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
     System.out.println(msg.trim());
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值