Java 将websocket入站通道适配器连接到网关的应答通道

Java 将websocket入站通道适配器连接到网关的应答通道,java,spring-integration,Java,Spring Integration,我在一个请求/回复场景中,我接收到需要通过相同的输入连接进行回复的请求。要给出响应,我需要向另一个系统发出websocket请求。现在,我正在以这种方式将输出通道连接到网关的应答通道(我正在使用转换器来调整传入消息): 这里的问题是我得到了一个错误: org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available WebSo

我在一个请求/回复场景中,我接收到需要通过相同的输入连接进行回复的请求。要给出响应,我需要向另一个系统发出websocket请求。现在,我正在以这种方式将输出通道连接到网关的应答通道(我正在使用转换器来调整传入消息):

这里的问题是我得到了一个错误:

org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
WebSocket本质上是双向的,所以我可以在不发送任何消息的情况下获取任何消息,它不是真正的请求/回复通道,但我需要以这种方式使用它。websocket服务器只向以前的“请求”消息发送“回复”消息

我需要通过返回网关得到websocket的响应


更新1

我在网关后添加了一个标题enricher,以将回复和错误通道字符串化并存储到注册表中:

(添加了“ReplyChannel注册表”频道)


现在的问题是。。。如何检索这些回复和错误通道?在通过系统的消息中,我有一个唯一的Id,我可以将其添加到头中,但是如何从这个来自websocket的相关Id获得回复和错误通道呢

更新2(已解决)

我想这种情况很常见。请求到达您的API,要响应此请求,您必须通过中断请求/应答模式的通道从另一个系统获取信息

在某个地方,您需要存储从请求提取的唯一id和它到达的通道之间的映射。需要使用从其他系统获得的数据重新创建此唯一id,否则无法恢复原始通道

步骤如下:

  • 请求来了
  • 使用
    网关
    组件的
    回复频道
    属性
  • 使用
    标题充实器
    组件将replyChannel字符串化(请参见更新1)。您不能有
    映射
    映射(id/频道),您需要对频道进行字符串化
  • 询问回复数据
  • 获取响应数据
  • 现在,您需要通过相同的原始连接发送回复
  • 为此,请使用另一个
    标题充实器
    组件。我们的想法是设置返回网关的消息的
    回复通道
    (确保消息的类与网关的返回类匹配),Spring将自动将“临时内部点对点”(我们之前字符串化的)链接到网关的
    回复通道
    。魔法

    
    

  • 完成了


  • 您正在丢失网关的
    replyChannel
    标题;它是活动对象,无法通过websocket发送


    尝试使用-将频道转换为字符串,并将频道存储在注册表中;websocket服务器必须返回字符串值头,这样才能正确关联以将通道从注册表中取出。

    应答和错误通道已正确字符串化,并可能存储在注册表中。我还添加了一个correlationId头,我可以在那里存储一个唯一的Id。现在我可以根据correlationId头属性从注册表检索回复通道了吗;但是,只要发送到网关的
    回复频道
    的消息具有带有适当字符串值的
    回复频道
    头,框架就会自动执行此操作。它不使用correlationId标头,而是使用带有字符串化值的
    replyChannel
    标头在注册表中查找频道。
    CLIENT -> gateway -> transformer -> wsClient -> SERVER -> wsClient -> transformer -> gateway-reply
    
    org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
    
    <int:gateway id="emrInboundGateway"
      service-interface="com.roche.iconnect.emr.core.EmrMessageInjector">
      <int:method name="injectMessage" request-channel="replyChannelRegistry" reply-channel="emrOutboundMessageTransformedChannel"/>
    </int:gateway>
    
    <beans:bean id="integrationHeaderChannelRegistry"
      class="org.springframework.integration.channel.DefaultHeaderChannelRegistry">
      <beans:constructor-arg index="0" value="${config.timeout}"/>
    </beans:bean>
    
    <int:header-enricher input-channel="replyChannelRegistry" output-channel="emrInboundMessageTransformerChannel">
      <int:header-channels-to-string time-to-live-expression="${config.timeout}"/>
      <int:correlation-id value="CORRELATION_ID_TEST"/>
    </int:header-enricher>