Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Netty-根据输入消息将结果作为StringEncoder或ObjectEncoder发送给客户端?_Java_Sockets_Netty - Fatal编程技术网

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

Java Netty-根据输入消息将结果作为StringEncoder或ObjectEncoder发送给客户端?,java,sockets,netty,Java,Sockets,Netty,我是Netty的新手,到目前为止,有一个可以使用StringEncoder和StringDecoder处理字符串消息的工作客户端服务器,例如: ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.clas

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

        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,服务器发回:ok

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

我知道ObjectEncoder似乎是一种方法。但是,它还将应该是字符串的响应序列化到序列化对象,同时它应该为某些特定消息(例如:get_object only)执行此操作


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

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

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

p.replace("encoder", "encoder", new YourObjectEncoder());
谢谢你的建议

当服务器接收到消息并将响应写入客户端时,它可以动态地切换编码器,如下面的代码所示

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

我像您提到的那样尝试了默认值是ObjectEncoder,并更改为StringEncoder以测试ctx.channel.pipeline.removeObjectEncoder.class;ctx.channel.pipeline.addLastnew StringEncoder;但客户端收到的却是空的。请确保将其添加到正确的位置。我上次提到是因为我不知道你的编码器在哪里。您最好使用pipeline.replace方法。我已经编辑了答案。
@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();
}