java - 将 websocket 入站 channel 适配器连接到网关的回复 channel

标签 java spring-integration

我处于请求/回复场景,并且收到需要通过同一输入连接回复的请求。为了给出响应,我需要向另一个系统发出 websocket 请求。现在,我正在以这种方式将输出 channel 连接到网关的回复 channel (我使用变压器来调整传入消息):

<int:channel id="emrOutboundMessageTransformedChannel"/>
<int:channel id="emrInboundMessageTransformerChannel"/>
<int:channel id="emrOutboundChannel"/>
<int:channel id="cloudOutboundChannel"/>

<!-- Server WebSocket -->

<beans:bean id="webSocketClient"
  class="org.springframework.web.socket.client.standard.StandardWebSocketClient"/>

<int-websocket:client-container id="webSocketClientContainer"
  client="webSocketClient"
  uri="ws://${cloud.webSocket.host}:${cloud.webSocket.port}"/>

<!-- Client Inbound -->

<int:gateway id="emrInboundGateway"
  service-interface="com.roche.iconnect.emr.core.EmrMessageInjector">
  <int:method name="injectMessage" request-channel="emrInboundMessageTransformerChannel" reply-channel="emrOutboundMessageTransformedChannel"/>
</int:gateway>

<int:transformer
  id="emrInboundTransformer"
  input-channel="emrInboundMessageTransformerChannel"
  output-channel="cloudOutboundChannel"
  method="convertEmrMessageToGenericMessage">
  <beans:bean class="com.roche.iconnect.emr.EmrMessageAdapter"/>
</int:transformer>

<!-- Client Outbound -->

<int:transformer
  id="emrOutboundTransformer"
  input-channel="emrOutboundChannel"
  output-channel="emrOutboundMessageTransformedChannel"
  method="convertGenericMessageToEmrMessage">
  <beans:bean class="com.roche.iconnect.emr.EmrMessageAdapter"/>
</int:transformer>

<!-- Server Inbound -->

<int-websocket:inbound-channel-adapter id="webSocketClientInboundAdapter"
  container="webSocketClientContainer"
  channel="emrOutboundChannel"/>

<int-websocket:outbound-channel-adapter id="webSocketClientOutboundAdapter"
  container="webSocketClientContainer"
  channel="cloudOutboundChannel"/>

它基本上是像这样改变组件:

CLIENT -> gateway -> transformer -> wsClient -> SERVER -> wsClient -> transformer -> gateway-reply

这里的问题是我收到错误:

org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available

Websockets 本质上是双向的,因此我可以在不发送任何内容的情况下获取任何消息,这不是真正的请求/回复 channel ,但我需要以这种方式使用它。 websocket 服务器只发送“回复”消息到之前的“请求”消息。

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

<小时/>

更新1

Header enricher registry

我在网关之后添加了一个 header 丰富器,以字符串化并将回复和错误 channel 存储到注册表中:

(添加了“replyChannelRegistry” channel )

<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>

现在的问题是...我如何检索这些回复和错误 channel ?在通过系统的消息中,我有一个可以添加到 header 的唯一 ID,但是如何从来自 Websocket 的相关 ID 中获取回复和错误 channel ?

更新 2(已解决)

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

您需要在某个地方存储您需要从请求中提取的唯一 ID 与请求到达的 channel 之间的映射。这个唯一的 ID 需要使用您从其他系统获取的数据重新创建,否则您无法恢复原始 channel 。

步骤是:

  1. 请求来了。
  2. 使用reply-channel gateway的属性(property)组件。
  3. 使用header-enricher对replyChannel进行字符串化组件(请参阅更新 1)。您不能拥有 Map<String, MessageChannel>映射(id/ channel ),您需要对 channel 进行字符串化。
  4. 请求响应数据。
  5. 获取响应数据。
  6. 现在您需要通过同一原始连接发送回复。
  7. 为此,请使用另一个 header-enricher成分。这个想法是设置 replyChannel将返回到网关的消息的类型(确保消息的类与网关的返回类匹配),Spring 会自动将“时间内部点对点”(我们之前字符串化的那个)链接到reply-channel的网关。魔法!

    <int:header-enricher input-channel="recoverOriginalChannel" output-channel="gatewayReplyChannel"> <int:reply-channel ref="yourBean" method="enrichReplyChannelHeader" /> </int:header-enricher>

  8. 完成!

最佳答案

您正在丢失网关的 replyChannel header ;它是一个 Activity 对象,无法通过 websocket 发送。

尝试使用 message channel registry - 将 channel 转换为字符串,并将 channel 存储在注册表中; websocket 服务器必须返回字符串值 header ,以便可以正确关联以从注册表中获取 channel 。

关于java - 将 websocket 入站 channel 适配器连接到网关的回复 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45938571/

相关文章:

java - 当我向 URL 发布 https 请求时出现 "unable to find valid certification path to requested target"

java - 性能改进 30 分钟内 : How to read only last 10 lines of 100, 000 个文件

java - 为什么当 ftp java dsl 配置被引入 spring 集成核心时过滤器行为发生了变化

spring - Kafka Spring 集成 : Headers not coming for kafka consumer

java - RabbitMQ 将消息分组为一条消息,即合并消息

java - 使用 WebClient/Spring Boot 2 将 REST 响应映射到 Mono<SomeClass> 的正确方法

Java替换字符串中的所有方括号

java - 如何在Windows中模仿Unix文件系统?

java - 如何将像 Quickfixj 这样的 TCP 服务器实现集成到 Spring-Integration 项目中?

java - 避免从不同的服务获取文件服务器的相同文件