在Netty中使用管道外的DelimiterBasedFrameDecoder,StringEncoder等

时间:2014-11-25 17:01:26

标签: java netty

我正在使用Netty开发TCP服务器。我知道通常的用法是创建ServerBootstrap并将Initializer对象传递给childHandler()方法。在Initializer中有一个initChannel方法,我们用一堆addLast命令设置管道,添加DelimiterBasedFrameDecoder,StringEncoder等东西。这假设我们先验知道我们总是得到文本/字符串消息。

但是,我想实现像LineReceiver这样的python Twisted Protocols中存在的功能,我们可以在原始模式和线路模式之间来回切换。是的一种方法是动态地从管道中删除和添加项目。但我想知道为什么我不能使用一个使用基本ChannelInitializer的最小管道,其中处理程序只是ChannelInboundHandlerAdapter的扩展,这是否有任何充分的理由。这样处理程序中的channelRead方法只处理原始字节(在ByteBuf中)。如果我想使用行模式,我是否可以在channelRead方法中使用DelimiterBasedFrameDecoder,StringEncoder等,即直接调用它们并在管道上下文之外使用它们?我有什么理由不这样做吗?

2 个答案:

答案 0 :(得分:1)

可以将所有编码器/解码器逻辑放入处理程序中,但从架构角度来看这是个坏主意。

最好编写新的编解码器(编码器/解码器),甚至可能基于它们,你可以查看StringEncoder或StringDecoder内部甚至DelimiterBasedFrameDecoder以了解如何做到这一点,实际上它们非常简单,或者在netty网站上查看它们如何实现TimeEncoder。

之后,编解码器将有机会单独测试,处理程序和代码将更加清晰。

答案 1 :(得分:1)

一个简单的比较:

  • 首先,您必须知道这些编解码器是如何工作的......
    • 只要没有足够的数据来自传入的消息(如DelimiterBasedFrameDecoder中所述),他们中的一些人会使用保存数据的上下文。
    • 有些人需要你写一些额外的方法,所以按照自己的方式行事不会妨碍你根据需要编写额外的方法。
    • 有些人正在使用处理程序的上下文(ChannelHandlerContext),即使很少,也可以存储一些内部(会话等)。
  • 树调用:所以你需要“手动”维护相同的行为,手动将正确的参数传递给每个(至少ChannelHandlerContext)。不确定你有任何收获。此外,管道是高效的,而不是在不需要时重新分配。
  • 内存:因为您需要为每个通道创建一个(因为它们不可共享,如果它们是,那么管道相同),这与在管道中创建一个相同的成本。所以从记忆方面来说,并不是更好。
  • 初始化:手动添加/删除管道,无需维护自己正确的调用顺序,我认为比手动完成所有操作更容易,分配,将其保存在私有channelhandler属性中。< / LI>
  • 行为:有些人可以依赖Netty上下文(ChannelHandlerContext)来正常工作(例如CompatibleObjectEncoderMarshallingDecoder)。如果这个ChannelHandlerContext不是由Netty构建的,它会工作吗?不知道......但是你需要确保编解码器就像你知道的那样。如果它被更改(因为外部API是相同的,但它实现它的方式发生了变化,因此你的行为也发生了变化),你必须知道它或你的代码可能会失败,你不会知道为什么......

所以在简历中,我没有看到任何手动使用这些代码的优势,而不是根据需要将它们插入/删除到管道中,但是如果内部实现在您没有注意到并且它破坏了您的内部实现时发生了变化,我确实看到了风险“非标准”逻辑...

在那之后,没有什么是不可能的,所以你的选择;-)但是正如其他评论中所提到的,你可能想要编写自己的编解码器,从现有的编解码器中激励自己......