使用netty默认编解码器编写一个聊天室

本文通过使用Netty的默认编解码器,详细介绍了如何构建一个简单的聊天服务器和客户端。服务器端创建了处理器,用于接收和广播消息,客户端则实现了消息发送和接收的处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • server
public class ChatRoomServer {
  public static void main(String[] args) throws InterruptedException {
    EventLoopGroup boosGroup = new NioEventLoopGroup(1);
    EventLoopGroup workGroup = new NioEventLoopGroup();
    try {
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap.group(boosGroup, workGroup)
          .channel(NioServerSocketChannel.class)
          .option(ChannelOption.SO_BACKLOG, 1024)
          .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());
              pipeline.addLast(new ChatRoomServerHandler());
            }
          });
      System.out.println("Netty server start...");
      ChannelFuture channelFuture = bootstrap.bind(8090).sync();
      channelFuture.addListener((ChannelFutureListener) channelFuture1 -> {
        if (channelFuture1.isSuccess()) {
          System.out.println("success monitor port 8090");
        } else {
          System.out.println("Failed monitor port 8090");
        }
      });
      channelFuture.channel().closeFuture().sync();
    } finally {
      boosGroup.shutdownGracefully();
      workGroup.shutdownGracefully();
    }
  }
}

  • server handler
public class ChatRoomServerHandler extends SimpleChannelInboundHandler<String> {

  private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

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

  /**
   * 表示channel处于就绪状态
   * @param ctx
   * @throws Exception
   */
  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception {
    Channel channel = ctx.channel();
    String msg = "client" + channel.remoteAddress() + " is online" + sdf.format(new Date()) + "\n";
    channelGroup.writeAndFlush(msg);
    // 将当前channel加入channelGroup
    channelGroup.add(channel);
    System.out.println(msg);
  }

  /**
   * 表示channel处于不活跃状态
   * @param ctx
   * @throws Exception
   */
  @Override
  public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    Channel channel = ctx.channel();
    String msg = "client" + channel.remoteAddress() + " is offline" + sdf.format(new Date()) + "\n";
    channelGroup.writeAndFlush(msg);
    System.out.println(msg);
  }

  /**
   * 读取数据
   * @param ctx
   * @param msg
   * @throws Exception
   */
  @Override
  protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    Channel channel = ctx.channel();
    String receiveData = "client" + channel.remoteAddress() + "send message" + msg + "\n";

    channelGroup.forEach(ch -> {
      if (channel != ch) { //不是当前的channel,转发消息
        ch.writeAndFlush(receiveData);
      } else {
        ch.writeAndFlush("Send a message by myself:" + msg + "\n");
      }
    });
  }

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

  • client
public class ChatRoomClient {

  public static void main(String[] args) throws InterruptedException {
    EventLoopGroup group = new NioEventLoopGroup();
    Bootstrap bootstrap = new Bootstrap();
    try {
      bootstrap.group(group)
          .channel(NioSocketChannel.class)
          .handler(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());
              pipeline.addLast(new ChatRoomClientHandler());
            }
          });
      System.out.println("Netty client start");
      ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8090).sync();
      channelFuture.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully();
    }
  }
}
  • client handler
public class ChatRoomClientHandler extends SimpleChannelInboundHandler<String> {

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    System.out.println("receive msg: " + msg);
  }

  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception {
    ByteBuf buf = Unpooled.copiedBuffer("Hello Server", CharsetUtil.UTF_8);
    ctx.writeAndFlush(buf);
  }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值