【问题标题】:How to make Netty client read entire response如何让 Netty 客户端读取整个响应
【发布时间】:2016-11-08 12:52:11
【问题描述】:

我有一个使用 TCP 套接字连接与 COBOL 服务器通信的 Camel 路由。路线基本上是这样的:

<route>
      <from uri="direct:sendMessage" />
      <log message="Sending message to server: ${body}" />
      <to uri="netty4:tcp://hostname:1234?requestTimeout=2000&amp;encoding=windows-1252" />
      <log message="Received response from server: ${body}" />
</route>

调用此路由会导致以下异常:

Failed delivery for (MessageId: ID-vmuxfusepoc01-34999-1467706512020-14-2 on ExchangeId: ID-vmuxfusepoc01-34999-1467706512020-14-1). Exhausted after delivery attempt: 1 caught: io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 1048576: 1008807217 - discarded

Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
[sendMessage       ] [to51              ] [direct:sendMessage                                                            ] [       697]
[sendMessage       ] [log60             ] [log                                                                           ] [         0]
[sendMessage       ] [to53              ] [netty4:tcp://jadev:7616?requestTimeout=2000&encoding=windows-1252             ] [       691]

Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
    Id                  ID-vmuxfusepoc01-34999-1467706512020-14-1
    ExchangePattern     InOut
    Headers             {breadcrumbId=ID-vmuxfusepoc01-34999-1467706512020-14-2, CamelHttpMethod=POST, CamelHttpPath=, CamelHttpQuery=null, CamelHttpServletRequest=(POST /message)@927654619 org.eclipse.jetty.server.Request@374ae2db, CamelHttpServletResponse=HTTP/1.1 500 
Content-Type: text/plain;charset=ISO-8859-1

, CamelHttpUri=/message, CamelHttpUrl=http://localhost:8282/message, CamelRedelivered=false, CamelRedeliveryCounter=0, CamelServletContextPath=/message, Content-Length=690, Content-Type=null, Host=localhost:8282}
    BodyType            String
    Body                uid:dev2016070412325814024903532ºS:bookinfoºbkd0001:017953491ºcmn0001:wdedul01
]

Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------

io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 1048576: 1008807217 - discarded
  at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:501)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:477)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:403)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:69)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:315)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:229)[io.netty:netty-codec:4.0.27.Final]
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:339)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:324)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:847)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)[io.netty:netty-transport:4.0.27.Final]
  at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111)[io.netty:netty-common:4.0.27.Final]
  at java.lang.Thread.run(Thread.java:745)[:1.7.0_101]

textline=true 添加到netty url 后,请求正确发送,但Netty 仅将服务器响应的第一行返回给Camel。服务器返回大约 100 行文本,然后关闭连接。

我尝试过使用 StringEncoder 和 StringDecoder,但这给了我与 'textline=true' 相同的结果。

我的问题是:如何配置 Netty 以将服务器的整个响应作为字符串返回。消息分隔符无关紧要,因为在服务器关闭连接之前将返回 1 条消息。

【问题讨论】:

    标签: apache-camel netty


    【解决方案1】:

    由于您无法保证在一次操作中会读取整个消息,因此您需要实现自己的 ByteToMessageDecoder 来理解所使用的框架。

    【讨论】:

      猜你喜欢
      • 2019-05-18
      • 1970-01-01
      • 2012-07-19
      • 2012-02-21
      • 2014-06-01
      • 1970-01-01
      • 2016-12-03
      • 2012-06-30
      • 2021-08-24
      相关资源
      最近更新 更多