我在Netty之上實現爲SIP服務器,並且所有內容都使用Netty 3.x正常工作。不過,我決定升級到Netty 4,因爲它有明確的線程模型,但事情發生了很大的變化,我迷了路。我最初的問題(我得到的大部分工作,但它對我來說不太合理)是關於MessageToByteEncoder
和爲什麼我必須自己打電話ctx.writeAndFlush
。爲什麼在使用MessageToByteEncoder時需要調用ctx.writeAndFlush
自舉:
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
,這是非常簡單的,它的代碼在下面找到。另外請注意,我一直在玩弄各種選擇,但如可疑,我還沒有找到任何改變這種行爲的組合。
編碼器:
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);
}
}
的SipMessage
和SipParser
等都是從我的其他開源項目pkts.io拍攝,但不是這個問題真正相關。只要知道SipMessage.toBuffer()
基本上只是吐出原始byte[]
,然後我轉移到由Netty傳入的ByteBuff
。
上述代碼不起作用,除非我做ctx.writeAndFlush(out)
。不過,我認爲,就像在Netty 3中一樣,這個稍高一點的編碼器的目的是爲了讓我擺脫這些細節。通過代碼步驟調試ByteBuf
寫入ctx
但不刷新,我猜是它沒有出現在插座上的原因。所以,我的問題是簡單的:
- 爲什麼我要叫
ctx.writeAndFlush
自己,當我使用的是SipMessageEncoder
。 Factorial示例中的NumberEncoder
未執行此操作,並查看HTTP編解碼器,我無法看到它做了那麼顯然我缺少明顯的東西。 - 此外,
ByteBuf
正在寫入上下文,但永遠不會刷新,所以它會在什麼時候?我試圖通過一個單獨的TCP連接(使用sipp)來推動大量流量,看看它是否最終會強制刷新但不會顯示。
順便說一句,我也試過用MessageToMessageEncoder
並通過上下文分配ByteBuf並把它添加到List
但相同的結果。
Btw2 - 我使用了Netty 4.0.10.Final
感謝,
/喬納斯
喜伊戈爾, 不,我不叫齊平,並沒有實際的幫助,因爲我不寫任何東西我自己。也許我誤解了MessageToByteEncoder的使用,但我的印象是,我將一個對象轉換爲另一個對象(在這種情況下是ByteBuf),並在稍後的一段時間內將其寫入並刷新,我相信我只是錯過了一些非常明顯的東西,如果我做了ctx。它在bytebuf上的writeAndFlush工作,但是我不明白MessageToByteEncoder的重點。 – jonbo372
嗨,伊戈爾,其實我想我明白你的意思。不,我不會在我的SipMessageEncoder中調用flush,也許問題出在哪裏。我會給出一個去,如果這樣的作品,然後感謝讓我在正確的軌道上!非常感謝。我會盡快更新,但我首先嚐試實際工作:-) – jonbo372
您會發現,寫入通道的所有消息都駐留在輸出緩衝區中,直到您調用flush()爲止。主要使用場景如下:將消息寫入頻道,然後使用flush()。每條消息都由MessageToByteEncoder序列化。這裏不需要調用write()。在最後flush()之後,所有消息將被寫入該行。如果你在SipMessageEncoder中沒有調用flush()方法。 –