首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在使用ctx.writeAndFlush时必须调用MessageToByteEncoder

为什么在使用ctx.writeAndFlush时必须调用MessageToByteEncoder
EN

Stack Overflow用户
提问于 2013-10-13 20:18:18
回答 1查看 3.8K关注 0票数 1

我正在Netty之上实现SIP服务器,使用Netty3.x,一切都很正常。然而,由于定义良好的线程模型,我决定升级到Netty 4,但是事情发生了很大变化,我迷失了方向。我最初的问题是关于MessageToByteEncoder以及为什么我必须亲自打电话给ctx.writeAndFlush

鞋带:

代码语言:javascript
复制
private void createTCPListeningPoint() {
    this.serverBootstrap = new ServerBootstrap();

    this.serverBootstrap.group(this.bossGroup, this.workerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(final SocketChannel ch) throws Exception {
                    final ChannelPipeline pipeline = ch.pipeline();
                    pipeline.addLast("decoder", new SipFrameDecoder(Protocol.TCP));
                    pipeline.addLast("encoder", new SipMessageEncoder());
                    pipeline.addLast("handler", NettyNetworkStack.this.sipHandler);
                }
            });
    // .option(ChannelOption.SO_BACKLOG, 128)
    // .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
    // .childOption(ChannelOption.SO_KEEPALIVE, true)
    // .childOption(ChannelOption.TCP_NODELAY, true);
}

(绑定操作将在稍后进行,此处未显示)

由于传入管道正在工作(解码器和处理程序正在按应有的方式调用),唯一有趣的部分是SipMessageEncoder,它非常简单,其代码如下所示。还请注意,我一直在玩各种选项,但正如我所怀疑的那样,我还没有发现任何可以改变这种行为的组合。

编码器:

代码语言:javascript
复制
public final class SipMessageEncoder extends MessageToByteEncoder<SipMessage> {

@Override
protected void encode(final ChannelHandlerContext ctx, final SipMessage msg, final ByteBuf out) throws Exception {
    final Buffer b = msg.toBuffer();
    for (int i = 0; i < b.getReadableBytes(); ++i) {
        out.writeByte(b.getByte(i));
    }
    out.writeByte(SipParser.CR);
    out.writeByte(SipParser.LF);
    // ctx.writeAndFlush(out);
}

}

SipMessageSipParser等都取自我的其他开源项目pkts.io,但与这个问题并不真正相关。只需知道,SipMessage.toBuffer()本质上只是吐出一个原始byte[],然后我将其传输到Netty传入的ByteBuff中。

除非我做了ctx.writeAndFlush(out),否则上面的代码不能工作。然而,我认为,就像在Netty 3中一样,这个稍高级别的编码器的目的是保护我不受这些细节的影响。逐步调试ByteBuf被写入到ctx而不是刷新的代码,我猜这就是它没有出现在套接字上的原因。所以,我的问题很简单:

  • 为什么我在使用ctx.writeAndFlush时必须亲自打电话给SipMessageEncoder。阶乘示例中的NumberEncoder并没有做到这一点,通过HTTP,我也看不到它做到了这一点,所以很明显,我遗漏了一些显而易见的东西。
  • 而且,ByteBuf正在被写到上下文中,但是从来没有被刷新过,所以什么时候会这样呢?我试图通过一个TCP连接(使用sipp)来推动大量的流量,看看这是否最终会迫使同花顺,但没有,任何东西都不会出现。

顺便说一下,我还尝试使用MessageToMessageEncoder并通过上下文分配ByteBuf,并将其添加到List中,但结果是相同的。

Btw2 -我正在使用Netty4.0.10.Final

谢谢,

/Jonas

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-14 05:41:32

当向信道写入消息时,您会在其他地方调用刷新()吗?

"..you必须非常小心,不要忘记在编写东西之后调用ctx.flush()。或者,您可以使用快捷方法writeAndFlush()。“

实际上,您不需要在SipMessageEncoder中调用write(),因为消息将由父MessageToByteEncode编写。如果以前没有这样做,只需要调用刷新()就可以了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19349810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档