Spring 连接入站 HTTP 网关和出站 Websocket 网关的集成
Spring integration connecting inbound HTTP gateway with outbound Websocket gateaway
我想创建一个 REST 服务来开灯。我想要的架构如下:
- 许多嵌入式系统每个都连接到一个灯实例
- 每个嵌入式系统都有一个 websocket 客户端,连接到我的服务器
- 我的服务器拥有一项 REST 服务,允许网络客户端选择一个灯实例并将其打开
- REST 服务将有一个参数来指定一个 light 实例的引用,连接到系统并将消息发送到 websocket 客户端,等待来自客户端的确认消息,并且 return REST回答
我想使用 Spring 集成框架来完成此操作。我在想类似的东西:
请求:入站 HTTP GW -> 出站 Websocket GW
响应:入站 HTTP GW <- 入站 Websocket GW
问题是我不知道如何指定websocket客户端。知道怎么做吗?
目前,根据我收到的答案,这是提供解决方案的伪代码:
<!-- REST service to turn on the light -->
<int-http:inbound-gateway
supported-methods="POST"
request-channel="lightOnRequest"
reply-channel="lightOnResponse"
path="rest/lighton/{sessionId}">
<int-http:header name="{sessionId}" expression="{sessionId}"/>
</int-http:inbound-gateway>
<!-- We add a header SESSION_ID_HEADER to choose the websocket destination client -->
<int:header-enricher
input-channel="lightOnRequest"
output-channel="lightOnClientRequest">
<int:header
name="#{T(...SimpMessageHeaderAccessor).SESSION_ID_HEADER}"
expression="headers.sessionId"/>
<int:header-channels-to-string/>
</int:header-enricher>
<!-- Websocket out to client -->
<int-websocket:outbound-channel-adapter
channel="lightOnClientRequest"
container="serverWebSocketContainer" />
<!-- Response reception from the Websocket client -->
<int-websocket:inbound-channel-adapter
channel="lightOnClientResponse"
container="serverWebSocketContainer" />
<!-- The websocket client provides again the reply channel in the headers.
The bridge connects the response to the reply channel -->
<int:bridge input-channel="lightOnClientResponse"/>
很遗憾,您的问题不清楚。如果你的 WebSocket 东西是基于 Spring Integration WEbSocket 适配器,你有 ServerWebSocketContainer
其中有 getSessions()
到 return Map<String, WebSocketSession>
连接的客户端 session秒。因此,您可以通过 REST 服务向 end-users 公开。
当客户端 select 一个 session 并发送 HTTP 请求时,您可以简单地将带有 SimpMessageHeaderAccessor.SESSION_ID_HEADER
的消息转发到 <int-websocket:outbound-channel-adapter>
。
是的,您可以使用 <int-websocket:inbound-channel-adapter>
接收确认并将其自动转发到 REST 响应。但要实现这一点,您应该在 <header-enricher>
.
上使用 <header-channels-to-string>
将 TemporaryReplyChannel
从 <int-http:inbound-gateway>
转换为 String
您的客户端 WebSocket 应用程序必须确保 return 那些使用 replyChannel
请求 headers,当它向 session 发送确认时。通过 Spring 集成,一切都应该是透明的。
如果我遗漏了什么,请告诉我。
更新
很好。感谢您提供更多信息!你的配置看起来不错。一些说明: 1. 不需要 reply-channel="lightOnResponse"
:HTTP 入站网关非常好地等待来自 TemporaryReplyChannel
的回复。 2. 请在转发到 WebSocket 之前将 <header-channels-to-string>
添加到您的 <header-enricher>
。 3. <int-websocket:inbound-channel-adapter>
可以将其入站消息发送到简单的 bridge
:<bridge input-channel="lightOnClientResponse">
。在没有 output-channel
的情况下,它将消息从 headers 委托给 replyChannel
。因此,您的 HTTP 入站网关将收到适当的回复。
我想创建一个 REST 服务来开灯。我想要的架构如下:
- 许多嵌入式系统每个都连接到一个灯实例
- 每个嵌入式系统都有一个 websocket 客户端,连接到我的服务器
- 我的服务器拥有一项 REST 服务,允许网络客户端选择一个灯实例并将其打开
- REST 服务将有一个参数来指定一个 light 实例的引用,连接到系统并将消息发送到 websocket 客户端,等待来自客户端的确认消息,并且 return REST回答
我想使用 Spring 集成框架来完成此操作。我在想类似的东西:
请求:入站 HTTP GW -> 出站 Websocket GW
响应:入站 HTTP GW <- 入站 Websocket GW
问题是我不知道如何指定websocket客户端。知道怎么做吗?
目前,根据我收到的答案,这是提供解决方案的伪代码:
<!-- REST service to turn on the light -->
<int-http:inbound-gateway
supported-methods="POST"
request-channel="lightOnRequest"
reply-channel="lightOnResponse"
path="rest/lighton/{sessionId}">
<int-http:header name="{sessionId}" expression="{sessionId}"/>
</int-http:inbound-gateway>
<!-- We add a header SESSION_ID_HEADER to choose the websocket destination client -->
<int:header-enricher
input-channel="lightOnRequest"
output-channel="lightOnClientRequest">
<int:header
name="#{T(...SimpMessageHeaderAccessor).SESSION_ID_HEADER}"
expression="headers.sessionId"/>
<int:header-channels-to-string/>
</int:header-enricher>
<!-- Websocket out to client -->
<int-websocket:outbound-channel-adapter
channel="lightOnClientRequest"
container="serverWebSocketContainer" />
<!-- Response reception from the Websocket client -->
<int-websocket:inbound-channel-adapter
channel="lightOnClientResponse"
container="serverWebSocketContainer" />
<!-- The websocket client provides again the reply channel in the headers.
The bridge connects the response to the reply channel -->
<int:bridge input-channel="lightOnClientResponse"/>
很遗憾,您的问题不清楚。如果你的 WebSocket 东西是基于 Spring Integration WEbSocket 适配器,你有 ServerWebSocketContainer
其中有 getSessions()
到 return Map<String, WebSocketSession>
连接的客户端 session秒。因此,您可以通过 REST 服务向 end-users 公开。
当客户端 select 一个 session 并发送 HTTP 请求时,您可以简单地将带有 SimpMessageHeaderAccessor.SESSION_ID_HEADER
的消息转发到 <int-websocket:outbound-channel-adapter>
。
是的,您可以使用 <int-websocket:inbound-channel-adapter>
接收确认并将其自动转发到 REST 响应。但要实现这一点,您应该在 <header-enricher>
.
<header-channels-to-string>
将 TemporaryReplyChannel
从 <int-http:inbound-gateway>
转换为 String
您的客户端 WebSocket 应用程序必须确保 return 那些使用 replyChannel
请求 headers,当它向 session 发送确认时。通过 Spring 集成,一切都应该是透明的。
如果我遗漏了什么,请告诉我。
更新
很好。感谢您提供更多信息!你的配置看起来不错。一些说明: 1. 不需要 reply-channel="lightOnResponse"
:HTTP 入站网关非常好地等待来自 TemporaryReplyChannel
的回复。 2. 请在转发到 WebSocket 之前将 <header-channels-to-string>
添加到您的 <header-enricher>
。 3. <int-websocket:inbound-channel-adapter>
可以将其入站消息发送到简单的 bridge
:<bridge input-channel="lightOnClientResponse">
。在没有 output-channel
的情况下,它将消息从 headers 委托给 replyChannel
。因此,您的 HTTP 入站网关将收到适当的回复。