netty第一个程序,简单聊天程序

发布时间 2023-05-04 14:50:16作者: 月习

netty第一个程序,简单聊天程序。
server端和client端分别定义一个消息处理类

ChatServerHandler

public class ChatServerHandler extends SimpleChannelInboundHandler<String> {

    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.id().asShortText()+" online");
        channelGroup.writeAndFlush(channel.id().asShortText()+" online,users="+(channelGroup.size()+1));
        channelGroup.add(channel);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.id().asShortText()+" offline");
        channelGroup.writeAndFlush(channel.id().asShortText()+" offline,users="+channelGroup.size());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush(String.format("[%s-%s]:%s",channel.id().asShortText(),LocalTime.now().withNano(0),s));
    }

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

使用内置基本String 类型的InboundHandler。server端维护一个ChannelGroup,当有新连接进入,触发channelActive()方法,将channel放入group中,Group.writeAndFlush()向当前所有在线连接广播新上线通知。同理有连接断开触发channelInactive()方法,group向其它在线连接发送下线通知。某个channel有新消息向当前group所有channel进行广播发送。

ChatClientHandler

public class ChatClientHandler extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        System.out.println(s);
    }
}

client端消息处理比较简单,只打印监听到服务端发送的数据。

server端启动

EventLoopGroup group = new NioEventLoopGroup(1);
        ServerBootstrap boot = new ServerBootstrap();
        boot.group(group).channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        channel.pipeline()
                                .addLast(new StringDecoder())
                                .addLast(new StringEncoder())
                                .addLast(new ChatServerHandler());
                    }
                });
        System.out.println("server start");
        ChannelFuture future = boot.bind(8888).sync();
        
        future.channel().closeFuture().sync();
        group.shutdownGracefully();

绑定线程组、消息处理类及服务端口。消息处理类绑定了上面定义的ChatServerHandler,另外还有两个字符串编码解码内置处理类。编解码先理解下就是流数据都使用字符串字节解析,还没定义报文格式。

client端启动

EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap boot = new Bootstrap();
        boot.group(group).channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        channel.pipeline().addLast(new StringEncoder())
                                .addLast(new StringDecoder())
                                .addLast(new ChatClientHandler());
                    }
                });
        ChannelFuture future = boot.connect("localhost", 8888).sync();
        Channel channel = future.channel();
        //channel.writeAndFlush("hi");
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String msg = scanner.nextLine();
            channel.writeAndFlush(msg);
        }

        channel.closeFuture().sync();
        group.shutdownGracefully();

绑定线程组,handler处理类,连接server端端口。使用Scanner读取console输入,发送内容数据。