Problema de comunicación entre el cliente netty y el servidor: el cliente no puede recibir datos

El problema ocurre: el cliente puede enviar mensajes al servidor, pero los mensajes difundidos por el servidor no se pueden recibir en el cliente

Lado del cliente

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编码,编完之后才会写到服务器
    }
}

Lado del servidor

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);
    }
}

Después de una inspección, se descubrió que la razón era que no se agregó ninguna codificación de mensajes en el lado del servidor, lo que provocó que el lado del cliente no recibiera datos.
Método de procesamiento:

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();

Supongo que te gusta

Origin blog.csdn.net/qq_42599616/article/details/105459117
Recomendado
Clasificación