【Java】Netty中closeFuture添加监听事件示例

1. 需求

  • 客户端向服务端发送信息,服务端将信息打印
  • 客户端接收键盘输入到信息循环向服务端发送信息
  • 客户端接收键盘输入‘q’时关闭

2.服务端代码

import io.netty.bootstrap.ServerBootstrap;`在这里插入代码片`
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;

@Slf4j
public class Server {
    public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup(2);
        ServerBootstrap serverBootstrap = new ServerBootstrap()
                .group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast("handler1", new ChannelInboundHandlerAdapter() {
                            @Override                                         // ByteBuf
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                ByteBuf buf = (ByteBuf) msg;
                                String s = buf.toString(Charset.defaultCharset());
                                log.debug(s);
                            }
                        });

                    }
                });
        ChannelFuture channelFuture = serverBootstrap.bind(8080);
    }
}

客户端代码

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import java.net.InetSocketAddress;
import java.util.Scanner;

@Slf4j
public class Client {
    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        ChannelFuture channelFuture = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override // 在连接建立后被调用
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8080));
        System.out.println(channelFuture.getClass());
        Channel channel = channelFuture.sync().channel();
        log.debug("{}", channel);
        new Thread(()->{
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String line = scanner.nextLine();
                if ("q".equals(line)) {
                    channel.close(); // close 异步操作 1s 之后
                    break;
                }
                channel.writeAndFlush(line);
            }
        }, "input").start();

        // 获取 CloseFuture 对象, 1) 方法1 同步处理关闭, 2) 方法2 异步处理关闭
        ChannelFuture closeFuture = channel.closeFuture();

        /*
        方法一
        log.debug("waiting close...");
        closeFuture.sync();
        log.debug("处理关闭之后的操作");
        group.shutdownGracefully();
        */

        // 方法二
        closeFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                log.debug("处理关闭之后的操作");
                group.shutdownGracefully();// 优雅关闭
            }
        });
        // 方法三:拉姆达表达式简化方法二
        //closeFuture.addListener((ChannelFutureListener) future -> {
        //    log.debug("处理关闭之后的操作");
        //    group.shutdownGracefully();
        //});

    }
}

重点关注方法二
channel.closeFuture()获取处理closeFuture对象,使用其.addListener()方法添加一个ChannelFutureListener监听器,在关闭操作完成后执行相应的操作,然后调用group.shutdownGracefully()优雅地关闭事件循环组。

运行

依次运行服务端和客户端,客户端输入:
在这里插入图片描述
服务端输出:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Netty监听TCP端口,你需要创建一个ServerBootstrap实例,并配置它的各种参数,然后调用bind()方法来绑定并监听指定的端口。 以下是一个简单的示例代码: ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class TcpServer { private final int port; public TcpServer(int port) { this.port = port; } public void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(group) .channel(NioServerSocketChannel.class) .localAddress(port) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new YourChannelHandler()); } }); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { int port = 8080; // 设置监听的端口号 new TcpServer(port).start(); } } ``` 在上述代码,我们创建了一个NioEventLoopGroup来处理事件的处理,ServerBootstrap用于引导和绑定服务器,NioServerSocketChannel用于接受传入的连接,ChannelInitializer用于初始化处理新的SocketChannel。 你需要将"YourChannelHandler"替换为你自己的实际处理程序,以处理接收到的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值