import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;

import java.util.concurrent.ConcurrentHashMap;

public class MultiChatServer {
    private final int port;
    private final ConcurrentHashMap<String, ChannelHandlerContext> userMap = new ConcurrentHashMap<>();
    private final EventExecutorGroup group = new DefaultEventExecutorGroup(16);

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

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new StringDecoder(), new StringEncoder(), new MultiChatServerHandler(userMap, group));
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(port).sync();
            System.out.println('Server started on port ' + port);
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        new MultiChatServer(port).run();
    }
}

代码解释:

这段代码使用Netty框架构建了一个简单的多人聊天服务器。

1. 核心组件:

  • EventLoopGroup: Netty 使用 EventLoopGroup 来处理 I/O 操作。这里创建了两个 EventLoopGroup:
    • bossGroup:用于接收传入的连接请求。
    • workerGroup:用于处理已接受连接的 I/O 操作。
  • ServerBootstrap: 用于引导服务器启动过程,配置服务器相关参数。
  • ChannelInitializer: 用于配置 ChannelPipeline,添加数据编解码器和业务逻辑处理器。
  • ChannelHandler: 用于处理 I/O 事件和业务逻辑,本例中需要自定义 MultiChatServerHandler 来处理聊天逻辑。

2. 程序流程:

  1. 创建 MultiChatServer 实例,指定监听端口号。
  2. 调用 run() 方法启动服务器。
  3. 创建 bossGroupworkerGroup 实例。
  4. 创建 ServerBootstrap 实例,并进行如下配置:
    • 设置 EventLoopGroup。
    • 设置 Channel 类型为 NioServerSocketChannel
    • 设置 childHandler,添加 StringDecoderStringEncoder 和自定义的 MultiChatServerHandler 到 ChannelPipeline 中。
    • 设置 SO_BACKLOG 选项,用于指定连接队列大小。
    • 设置 SO_KEEPALIVE 选项,用于保持连接活跃。
  5. 绑定端口并启动服务器。
  6. 等待服务器关闭。
  7. 关闭 workerGroupbossGroup

3. MultiChatServerHandler (代码未给出):

MultiChatServerHandler 是处理聊天逻辑的核心类,需要实现以下功能:

  • 用户登录:将新连接的客户端添加到 userMap 中。
  • 消息广播:将接收到的消息广播给所有在线用户。
  • 用户退出:将断开连接的客户端从 userMap 中移除。

总结:

这段代码提供了一个基于 Netty 的多人聊天服务器的基本框架,开发者可以根据需求扩展 MultiChatServerHandler 中的逻辑,实现更复杂的功能,例如私聊、群聊等。

基于Netty的多人聊天服务器实现

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

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