首先,需要创建一个服务器来监听客户端连接请求,并处理来自客户端的消息。以下是一个简单的 Netty 聊天服务器的示例代码:

public class ChatServer {
    private final int port;

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

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap()
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChatServerInitializer());
            ChannelFuture future = bootstrap.bind(port).sync();
            System.out.println('Chat server started on port ' + port);
            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

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

在上面的代码中,我们创建了一个ChatServer类,它包含一个构造函数来指定服务器监听的端口号,并且有一个run()方法来启动服务器。在run()方法中,我们创建了两个EventLoopGroup,一个用于监听连接请求的bossGroup,另一个用于处理客户端请求的workerGroup。我们使用ServerBootstrap类来设置服务器的配置,包括使用NioServerSocketChannel通道、注册ChatServerInitializer类来处理客户端请求等。最后,我们绑定端口并等待服务器关闭。

接下来,我们需要创建一个ChatServerInitializer类来初始化服务器的通道管道(ChannelPipeline),并添加处理器来处理客户端请求。以下是一个示例代码:

public class ChatServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new ChatServerHandler());
    }
}

ChatServerInitializer类中,我们重写initChannel()方法来初始化通道管道。首先,我们添加一个DelimiterBasedFrameDecoder处理器来解决粘包和拆包问题;然后,我们添加StringDecoderStringEncoder处理器来将字节流转换为字符串,并将字符串转换为字节流;最后,我们添加一个自定义的ChatServerHandler处理器来处理客户端请求。

现在,我们需要创建一个ChatServerHandler类来实现自定义的处理器。以下是一个示例代码:

public class ChatServerHandler extends SimpleChannelInboundHandler<String> {
    private static final Map<Channel, String> clients = new ConcurrentHashMap<>();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        clients.put(channel, 'anonymous');
        System.out.println('Client ' + channel.remoteAddress() + ' connected');
        channel.writeAndFlush('Welcome to the chat room!
');
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        clients.remove(channel);
        System.out.println('Client ' + channel.remoteAddress() + ' disconnected');
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();
        String name = clients.get(channel);
        if (name.equals('anonymous')) {
            clients.put(channel, msg.trim());
            channel.writeAndFlush('Welcome, ' + msg.trim() + '!
');
        } else {
            broadcast(channel, name + ': ' + msg);
        }
    }

    private void broadcast(Channel sender, String message) {
        for (Channel channel : clients.keySet()) {
            if (channel != sender) {
                channel.writeAndFlush(message + '
');
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel channel = ctx.channel();
        clients.remove(channel);
        System.out.println('Client ' + channel.remoteAddress() + ' caused exception: ' + cause.getMessage());
        ctx.close();
    }
}

ChatServerHandler类中,我们继承了SimpleChannelInboundHandler类,并重写了几个方法,包括channelActive()channelInactive()channelRead0()exceptionCaught()等。在channelActive()方法中,我们添加了一个新的客户端到clients映射中,并欢迎客户端加入聊天室;在channelInactive()方法中,我们从clients映射中删除客户端,并记录客户端断开连接的消息;在channelRead0()方法中,我们根据客户端发送的消息来处理不同的情况,如果是第一次连接,则将客户端名称添加到clients映射中,并欢迎客户端加入聊天室;否则,将客户端发送的消息广播给其他客户端;在broadcast()方法中,我们遍历clients映射中的所有客户端,并将消息发送给除发送者之外的所有客户端;在exceptionCaught()方法中,我们处理客户端异常,并从clients映射中删除客户端。

现在,我们已经完成了一个基本的 Netty 聊天服务器,可以使用 telnet 或其他 TCP 客户端连接到该服务器,并实现聊天功能。

用 Netty 实现简单的聊天功能 - Java 代码示例

原文地址: https://www.cveoy.top/t/topic/oOnX 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录