JBoss Fuse中从TCP到XML的二进制数据解码

JBoss Fuse中从TCP到XML的二进制数据解码,tcp,apache-camel,netty,jbossfuse,blueprint-osgi,Tcp,Apache Camel,Netty,Jbossfuse,Blueprint Osgi,一般来说,我是ESB新手,但我的任务是实现一个TCP读取器,它在JBoss Fuse中输出XML数据。我尝试过几种方法,但迄今为止效果有限 我从使用Camel Blueprint ArchType开始(因为这是大多数Fuse教程的基础)。然后,我定义了一个简单的路由,从一个Netty4输入开始,通过一个定制的解码器类运行,并记录结果 blueprint.xml <?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="ht

一般来说,我是ESB新手,但我的任务是实现一个TCP读取器,它在JBoss Fuse中输出XML数据。我尝试过几种方法,但迄今为止效果有限

我从使用Camel Blueprint ArchType开始(因为这是大多数Fuse教程的基础)。然后,我定义了一个简单的路由,从一个Netty4输入开始,通过一个定制的解码器类运行,并记录结果

blueprint.xml

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
       http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">

    <bean id="myMessageDecoder" class="com.mycompany.binaryreceiver.binaryreceiver.MyMessageDecoder" />

  <camelContext allowUseOriginalMessage="false" xmlns="http://camel.apache.org/schema/blueprint">
  <route>
    <from uri="netty4:tcp://localhost:9999?decoder=#myMessageDecoder&amp;sync=false"/>
    <log message="Message Received: ${body}"/>
  </route>
</camelContext>

</blueprint>
解码器只是检查缓冲区中是否有三个字节。如果有,那么它会将这些字节推送到MyMessage中,MyMessage提供了一个日志记录器可以访问的toString接口

显然,这只是一个示例,最终的消息要复杂得多,涉及可变长度的内容,但这说明了基本过程

这一切似乎都起作用了,如果我将字节流推入端口9999,记录器将输出预期值:

INFO  Message Received: MyMessage: { 1, 13, 58 }
INFO  Message Received: MyMessage: { 2, 36, 63 }
INFO  Message Received: MyMessage: { 3, 74, 5 }
INFO  Message Received: MyMessage: { 4, 12, 92 }
INFO  Message Received: MyMessage: { 5, 111, -121 }
INFO  Message Received: MyMessage: { 6, 0, 0 }
INFO  Message Received: MyMessage: { 7, 80, 64 }
INFO  Message Received: MyMessage: { 8, 0, 0 }
INFO  Message Received: MyMessage: { 9, 0, -116 }
INFO  Message Received: MyMessage: { 10, -108, 111 }
INFO  Message Received: MyMessage: { 11, -17, -100 }
INFO  Message Received: MyMessage: { 12, -35, -28 }
但是,在启动过程中,我收到以下消息:

[Blueprint Extender: 1] NettyConfiguration  WARN  
The decoder com.mycompany.binaryreceiver.binaryreceiver.MyMessageDecoder@2413a0f1
is not @Shareable or an ChannelHandlerFactory instance. The decoder cannot safely be used.
在查阅了警告之后,我发现了一些参考资料,这些资料似乎表明我在整个过程中都做得不正确,我应该通过Netty4 ChannelHandlerFactorys

是否有人有过执行类似二进制->XML流程的经验,可以评论或帮助执行这些任务的正确/推荐流程


这个警告是一个合理的问题,还是一种误导?我应该使用ChannelHandlerFactorys还是完全不同的方法?

请参阅camel-netty4文档中关于不可共享编码器或解码器的部分。这是您必须执行的所有文档:


我计划建立一个工厂,以尝试和处理解码器的实例化;然而,我很幸运,我真正需要的功能可以通过内置的长度字段解码器实现

<bean id="lengthFieldDecoder"
      class="org.apache.camel.component.netty4.ChannelHandlerFactories"
      factory-method="newLengthFieldBasedFrameDecoder">
  <argument value="10000" /> <!-- Max Frame Length -->
  <argument value="0" />     <!-- Length Field Offset -->
  <argument value="4" />     <!-- Length Field Length -->
  <argument value="0" />     <!-- Length Adjustment -->
  <argument value="4" />     <!-- Initial Bytes to Strip -->
</bean>

<camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint">
  <route>
    <from uri="netty4:tcp://localhost:9999?decoder=#lengthFieldDecoder&amp;
               clientMode=true&amp;sync=false"
          id="Netty4 TCP Client" />
    <log message="Message (Binary): ${body}" id="Log Binary"/>
  </route>
</camelContext>


尝试将
@Shareable
添加到您的自定义编解码器类根据API,它并不是那么简单:“请注意,ByteToMessageDecoder的子类不能用@Sharable注释。”[Link]()感谢您的帮助。这是否意味着基于ByteToMessageDecoder的解码器是不正确的方法,而我应该通过ChannelHandlerFactory来代替?或者只能在某些情况下使用解码器?
[Blueprint Extender: 1] NettyConfiguration  WARN  
The decoder com.mycompany.binaryreceiver.binaryreceiver.MyMessageDecoder@2413a0f1
is not @Shareable or an ChannelHandlerFactory instance. The decoder cannot safely be used.
<bean id="lengthFieldDecoder"
      class="org.apache.camel.component.netty4.ChannelHandlerFactories"
      factory-method="newLengthFieldBasedFrameDecoder">
  <argument value="10000" /> <!-- Max Frame Length -->
  <argument value="0" />     <!-- Length Field Offset -->
  <argument value="4" />     <!-- Length Field Length -->
  <argument value="0" />     <!-- Length Adjustment -->
  <argument value="4" />     <!-- Initial Bytes to Strip -->
</bean>

<camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint">
  <route>
    <from uri="netty4:tcp://localhost:9999?decoder=#lengthFieldDecoder&amp;
               clientMode=true&amp;sync=false"
          id="Netty4 TCP Client" />
    <log message="Message (Binary): ${body}" id="Log Binary"/>
  </route>
</camelContext>