Java Netty-根据输入消息将结果作为StringEncoder或ObjectEncoder发送到客户端吗?

时间:2018-10-23 07:34:50

标签: java sockets netty

我是Netty的新手,到目前为止,有一个工作的客户端服务器可以使用StringEncoder和StringDecoder处理String消息,例如:

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                       .channel(NioServerSocketChannel.class)
                       .handler(new LoggingHandler(LogLevel.TRACE))
                       .childHandler(new ChannelInitializer<SocketChannel>() {
                                            @Override
                                            public void initChannel(SocketChannel ch) throws Exception {
                                                ch.pipeline().addLast(
                                                    new LoggingHandler(LogLevel.TRACE),
                                                    new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()),
                                                    new StringEncoder(),
                                                    new StringDecoder(),
                                                    new ReceiveMessageCommunicatorHandler(localNode, inpeerNodeRegistry, outpeerNodeRegistry));

输入消息如下: excute_this ,服务器发回:确定

现在,我需要做的是服务器接收到一条新的文本消息: get_object ,它应该将序列化的邮件发送回任何客户端(例如:使用普通套接字的telnet或java应用程序)对象为字节数组。然后,在此客户端中,可以将该对象反序列化为Java对象。

我知道 ObjectEncoder()似乎是这样做的方法。但是,它还会将应为String的响应序列化为序列化的对象,而对某些特定消息则应这样做(例如: get_object )。

我该如何告诉Netty何时将结果编码为StringEncoder,何时将序列化对象编码为字节数组?

2 个答案:

答案 0 :(得分:1)

可以动态修改管道。收到 get_object 消息时,您只需删除StringEncoder并将ObjectEncoder添加到相关的ChannelInboundHandler

   ChannelPipeline p = ctx.pipeline();
    if (p.get(StringEncoder.class) != null) {
        p.remove(StringEncoder.class);
    }
    p.addLast(new YourObjectEncoder())

或者,如果您知道编码器的名称,则可以进行替换:

p.replace("encoder", "encoder", new YourObjectEncoder());

答案 1 :(得分:0)

感谢 Riyafa Abdul Hameed

的建议

当服务器收到消息并将响应写到客户端时,它可以按照此代码动态切换编码器。

@Override
protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
    InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
    MessageContainer messageContainer = new MessageContainer(message, address);
    log.debug("\n");
    log.debug("Message received: {}", message);

    // Handle received message and write result back to the sender
    Object response = this.handleMessage(messageContainer);
    if (response instanceof String) {
        ctx.channel().pipeline().names();
        ctx.channel().pipeline().remove(ObjectEncoder.class);
        ctx.channel().pipeline().addFirst(new StringEncoder());
    }

    if (response != null) {
        ctx.write(response);
        ctx.flush();
    }
    ctx.close();
}