Communication problem between netty client and server: the client cannot receive data

The problem occurs: the client can send messages to the server, but the messages broadcast by the server cannot be received on the client

Client side

public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
    
    
    protected void initChannel(SocketChannel socketChannel) throws Exception {
    
    
        socketChannel.pipeline()
                .addLast(new TankJoinMsgEncoder())  // 客户端通过编码发送至服务端
                .addLast(new TankJoinMsgDecoder())  // 服务端解码服务端广播的消息
                .addLast(new ClientHandler()); 
    }
}
class ClientHandler extends SimpleChannelInboundHandler<TankJoinMsg> {
    
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TankJoinMsg msg) throws Exception {
    
    
        if(msg.id.equals(TankFrame.INSTANCE.getMainTank().getId()) ||
                TankFrame.INSTANCE.findByUUID(msg.id)!=null ) return;
        System.out.println(msg);
        Tank t = new Tank(msg);
        TankFrame.INSTANCE.addTank(t);
        ctx.writeAndFlush(new TankJoinMsg(TankFrame.INSTANCE.getMainTank())); // 发送消息至server端
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    
    
        ctx.writeAndFlush(new TankJoinMsg(TankFrame.INSTANCE.getMainTank()));// 会通过TankJoinMsgEncoder编码,编完之后才会写到服务器
    }
}

Server side

public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

public void serverStart() {
    
    
        EventLoopGroup bossGroup = new NioEventLoopGroup(1); 
        EventLoopGroup workerGroup = new NioEventLoopGroup(2);

        ServerBootstrap sb = new ServerBootstrap(); // 辅助启动类
        try {
    
    
            ChannelFuture f = sb.group(bossGroup,workerGroup) // 指定线程池组
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
    
    
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
    
    
                            ChannelPipeline pl = socketChannel.pipeline();
                            pl.addLast(new TankJoinMsgDecoder())
                                .addLast(new ServerChildHandler());
                        }
                    })
                    .bind(9999)
                    .sync();
            ServerFrame.INSTANCE.updateServerMsg("server started!");
            f.channel().closeFuture().sync(); // close->ChannelFuture
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
class ServerChildHandler extends ChannelInboundHandlerAdapter{
    
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    
    
        Server.clients.add(ctx.channel());
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    
    
        cause.printStackTrace();
        // 删除出现异常的客户端channel,并关闭连接
        Server.clients.remove(ctx.channel());
        ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    
    
        ServerFrame.INSTANCE.updateClientMsg(msg.toString());
        Server.clients.writeAndFlush(msg);
    }
}

After some inspection, it was discovered that the reason was that no message encoding was added under the Server side, which caused the Client side to fail to receive data.
Processing method:

ChannelFuture f = sb.group(bossGroup,workerGroup) // 指定线程池组
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
    
    
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
    
    
                            ChannelPipeline pl = socketChannel.pipeline();
                            pl.addLast(new TankJoinMsgDecoder())
                                .addLast(new TankJoinMsgEncoder()) // 该位置加上消息编码
                                .addLast(new ServerChildHandler());
                        }
                    })
                    .bind(9999)
                    .sync();

Guess you like

Origin blog.csdn.net/qq_42599616/article/details/105459117