Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.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
Sockets 从不同的InboundChannelHandlerAdapter.channelRead调用writeAndFlush时出现问题_Sockets_Io_Netty - Fatal编程技术网

Sockets 从不同的InboundChannelHandlerAdapter.channelRead调用writeAndFlush时出现问题

Sockets 从不同的InboundChannelHandlerAdapter.channelRead调用writeAndFlush时出现问题,sockets,io,netty,Sockets,Io,Netty,我有一个问题,由于安全原因,我无法发布完整的代码。我的问题的要点是我有一个ServerBootstrap,创建如下: bossGroup = new NioEventLoopGroup(); workerGroup = new NioEventLoopGroup(); final ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.c

我有一个问题,由于安全原因,我无法发布完整的代码。我的问题的要点是我有一个ServerBootstrap,创建如下:

bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
final ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)                        
.childHandler(new ChannelInitializer<SocketChannel>() {

@Override
public void initChannel(SocketChannel ch) throws Exception {
                                ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, 3000));
                                //Adds the MQTT encoder and decoder
                                ch.pipeline().addLast("decoder", new MyMessageDecoder());
                                ch.pipeline().addLast("encoder", new MyMessageEncoder());
                                ch.pipeline().addLast(createMyHandler());
                            }
                        }).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_REUSEADDR, true)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .childOption(ChannelOption.SO_KEEPALIVE, true);

                // Bind and start to accept incoming connections.
                channelFuture = b.bind(listenAddress, listenPort);
其中MyClientHandler又是ChannelInboundHandlerAdapter的子类实例。一切正常,我收到来自服务器适配器的消息,我处理它们,然后将它们发送回相同的上下文。对于客户端处理程序,反之亦然

当我必须将某些消息从服务器或客户端处理程序代理到其他连接时,就会出现问题。再一次,我很抱歉不能发布太多代码,但我的主旨是:

serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
     if (msg instanceof myProxyingMessage) {
        if (ctx.channel().isActive()) {
             ctx.channel().writeAndFlush(someOtherMessage);
             **getClientHandler().writeAndFlush(myProxyingMessage);**
        }
     }
}
现在问题来了:粗体的客户机writeAndFlush从未实际写入消息字节,它不会抛出任何错误。ChannelFuture返回所有错误的成功、取消、完成。如果我在上面同步,它最终会因为代码中设置的连接超时的其他原因超时

我知道我还没有发布所有的代码,但我希望有人能提供一些提示和/或指针,帮助解决为什么不向客户机上下文写入代码的问题。我并不是一个多愁善感的专家,这段代码大部分是由别人写的。它们都是ChannelInboundHandlerAdapter的子类

如果有任何问题,请随时提问

*****编辑********* 我尝试使用以下测试代码将请求代理回不同的上下文/通道,即客户端通道:

public void proxyPubRec(int messageId) throws MQTTException {
        logger.log(logLevel, "proxying PUBREC to context:  " + debugContext());
        PubRecMessage pubRecMessage = new PubRecMessage();
        pubRecMessage.setMessageID(messageId);
        pubRecMessage.setRemainingLength(2);
        logger.log(logLevel, "pipeline writable flag:  " + ctx.pipeline().channel().isWritable());
        MyMQTTEncoder encoder = new MyMQTTEncoder();

        ByteBuf buff = null;
        try {
            buff = encoder.encode(pubRecMessage);
            ctx.channel().writeAndFlush(buff);

        } catch (Throwable t) {
            logger.log(Level.SEVERE, "unable to encode PUBREC");
        } finally {
            if (buff != null) {
                buff.release();
            }
        }
    }

    public class MyMQTTEncoder extends MQTTEncoder {
        public ByteBuf encode(AbstractMessage msg) {
            PooledByteBufAllocator allocator = new PooledByteBufAllocator();
            ByteBuf buf = allocator.buffer();
            try {
                super.encode(ctx, msg, buf);
            } catch (Throwable t) {
                logger.log(Level.SEVERE, "unable to encode PUBREC, " + t.getMessage());
            }
            return buf;
        }
    }
但是上面的第行:ctx.channel.writeAndFlushbuff没有向另一个通道写入-有没有关于调试此类问题的提示/技巧

其他消息必须是ByteBuf

那么,拿这个来说:

serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
     if (msg instanceof myProxyingMessage) {
        if (ctx.channel().isActive()) {
             ctx.channel().writeAndFlush(someOtherMessage);
             **getClientHandler().writeAndFlush(myProxyingMessage);**
        }
     }
}
。。。并将其替换为:

serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
     if (msg instanceof myProxyingMessage) {
        if (ctx.channel().isActive()) {
             ctx.channel().writeAndFlush(ByteBuf);
             **getClientHandler().writeAndFlush(myProxyingMessage);**
        }
     }
}

实际上,这是一个线程问题。我的一个线程被阻塞/等待,而其他线程正在向上下文写入,因此,写入被缓冲,而不被发送,即使是刷新。问题解决了


本质上,我将第一条消息代码放在一个可运行/执行器线程中,这允许它单独运行,以便第二次写入/响应能够写入上下文。在消息排序方面,这仍然存在一些潜在的问题,但这不是原始问题的主题。谢谢你的帮助

谢谢你的评论。我相信在这种情况下,实际上并不需要ByteBuf,因为我有一个负责字节处理的解码器/编码器。例如,MQTTDecoder/MQTTEncoder。我不是100%确定,但这个问题似乎与netty处理通道读/写的方式有关——在这种情况下,我从服务器上下文中读取内容后,正在写入一个不同的上下文,而写入操作从不出于任何原因推送/刷新内容。我不知道为什么。我试过了-请看我上面的编辑-它不起作用:虽然我很有希望…你能提供你用来转换其他消息的ByteBuf代码吗?事实上,这是一个线程问题。我的一个线程被阻塞/等待,而其他线程正在向上下文写入,因此,写入被缓冲,而不被发送,即使是刷新。问题解决了!:
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
     if (msg instanceof myProxyingMessage) {
        if (ctx.channel().isActive()) {
             ctx.channel().writeAndFlush(ByteBuf);
             **getClientHandler().writeAndFlush(myProxyingMessage);**
        }
     }
}