Netty (3) - para lograr la comunicación entre el cliente y de servidor de dos vías

Una idea básica

etapas de procesamiento de lectura y de escritura de lógica se inician mediante la adición de al procesador lógico Pipeline cadena de procesamiento de la lógica para leer y escribir datos en la conexión lógica.

  1. la conexión del cliente de devolución de llamada procesador lógico éxito channelActive()método

  2. El cliente y el servidor recibe datos de nuevo a la llamada de uno al otro procesador lógico channelRead()método.

  3. El cliente y el servidor de datos de escritura a la otra llamada writeAndFlush()método

  4. la transmisión de datos binarios cliente portador y la interacción del servidor esByteBuf

II. Proceso de Comunicación

[Volcar imagen no pasa la cadena, la estación de origen puede tener mecanismo de cadena de seguridad, se recomienda guardar la imagen abajo subido directamente (img-lxx6KkVY-1580725870430) (http://note.youdao.com/yws/res/9840/76DC2AB9464A4D1882346E496B1C9518)]

III. La implementación del Código

  • NIOServer
/**
 * @Auther: ARong
 * @Description: 服务端-客户端双向通信,服务端在接收到客户端信息后向客户端发出响应
 */
public class NIOServer {
    public static void main(String[] args) {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(); // 监听组
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(); // 工作组

        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class) //NIO模式
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    // 初始化channel
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new FirstServerHandler());
                    }
                }).bind(8000);
    }
}

  • NIOClient
/**
 * @Auther: ARong
 * @Description: 服务端-客户端双向通信,客户端向服务端发送信息
 */
public class NIOClient {
    public static void main(String[] args) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                // 责任链模式,添加第一次连接的客户端处理逻辑
                ch.pipeline().addLast(new FirstClientHandler());
            }
        });

        Channel channel = bootstrap.connect("127.0.0.1", 8000).channel();
        String message = String.format("HelloWorld From %s", new SimpleDateFormat("hh:mm:ss").format(new Date()));
        channel.writeAndFlush(message);
    }
}
  • FirstServerHandler
/**
 * @Auther: ARong
 * @Description: 服务端被首次连接的处理逻辑
 */
public class FirstServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    /*
     * @Author ARong
     * @Description 接收到服务端消息时触发
     * @Param [ctx, msg]
     * @return void
     **/
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println(String.format("服务端读取到数据%s From %s",
                byteBuf.toString(Charset.forName("utf-8")),
                getCurTime()));

        ByteBuf byteBuf1 = getByteBuf(ctx);
        ctx.channel().writeAndFlush(byteBuf1);
    }

    /*
     * @Author ARong
     * @Description 获取二进制抽象 ByteBuf
     * @Param [ctx]
     * @return io.netty.buffer.ByteBuf
     **/
    private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
        // 获取二进制抽象 ByteBuf
        ByteBuf buffer = ctx.alloc().buffer();

        // 准备数据,指定字符串的字符集为 utf-8
        String response = String.format("服务端返回HelloWorld From %s", getCurTime());
        byte[] bytes = response.getBytes(Charset.forName("utf-8"));

        // 填充数据到 ByteBuf
        buffer.writeBytes(bytes);

        return buffer;
    }

    private String getCurTime() {
        return new SimpleDateFormat("hh:mm:ss").format(new Date());
    }
}
  • FirstClientHandler
/**
 * @Auther: ARong
 * @Description: 首次连接的客户端处理逻辑
 */
public class FirstClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    /*
     * @Author ARong
     * @Description 客户端与服务端首次连接的处理逻辑
     * @Param [ctx]
     * @return void
     **/
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 编码数据
        ByteBuf byteBuf = getByteBuf(ctx);
        // 写回给服务端
        ctx.channel().writeAndFlush(byteBuf);
    }

    @Override
    /*
     * @Author ARong
     * @Description 接收到服务端消息时触发
     * @Param [ctx, msg]
     * @return void
     **/
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println(String.format("客户端读取到数据%s From %s",
                byteBuf.toString(Charset.forName("utf-8")),
                getCurTime()));
    }

    /*
     * @Author ARong
     * @Description 获取二进制抽象 ByteBuf
     * @Param [ctx]
     * @return io.netty.buffer.ByteBuf
     **/
    private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
        // 获取二进制抽象 ByteBuf
        ByteBuf buffer = ctx.alloc().buffer();

        // 准备数据,指定字符串的字符集为 utf-8
        String response = String.format("客户端返回HelloWorld From %s", getCurTime());
        byte[] bytes = response.getBytes(Charset.forName("utf-8"));

        // 填充数据到 ByteBuf
        buffer.writeBytes(bytes);

        return buffer;
    }

    private String getCurTime() {
        return new SimpleDateFormat("hh:mm:ss").format(new Date());
    }
}

A su vez inicia el cliente y el servidor, la comunicación de dos vías:

Aquí Insertar imagen Descripción

Publicados 309 artículos originales · ganado elogios 205 · Vistas de 300.000 +

Supongo que te gusta

Origin blog.csdn.net/pbrlovejava/article/details/104160163
Recomendado
Clasificación