Spring integration Spring集成连接入站HTTP网关和出站Websocket网关

Spring integration Spring集成连接入站HTTP网关和出站Websocket网关,spring-integration,spring-websocket,Spring Integration,Spring Websocket,我想创建一个REST服务来打开灯。我想要的架构如下所示: 许多嵌入式系统每个都连接到一个light实例 每个嵌入式系统都有一个websocket客户端,它连接到我的服务器 我的服务器拥有一个REST服务,它允许WebClient选择一个light实例并将其打开 REST服务将有一个参数来指定一个light实例的引用,该实例连接到系统并将消息发送到websocket客户端,等待客户端的确认消息,然后返回REST应答 我希望使用Spring集成框架来实现这一点。我在想这样的事情: 请求:入站HT

我想创建一个REST服务来打开灯。我想要的架构如下所示:

  • 许多嵌入式系统每个都连接到一个light实例
  • 每个嵌入式系统都有一个websocket客户端,它连接到我的服务器
  • 我的服务器拥有一个REST服务,它允许WebClient选择一个light实例并将其打开
  • REST服务将有一个参数来指定一个light实例的引用,该实例连接到系统并将消息发送到websocket客户端,等待客户端的确认消息,然后返回REST应答
我希望使用Spring集成框架来实现这一点。我在想这样的事情:

请求:入站HTTP GW->出站Websocket GW


回答:很遗憾,您的问题不清楚。如果您的WebSocket是基于Spring集成WebSocket适配器的,那么您就有了
ServerWebSocketContainer
,它有
getSessions()
来返回连接的客户端会话的
Map
。因此,您可以通过REST服务向最终用户公开

当客户端选择一个会话并发送HTTP请求时,您只需使用
SimpMessageHeaderAccessor.session_ID_头
将该消息转发到

是的,您可以使用
接收确认,并自动将其转发给REST响应。但要实现这一点,您应该使用
上的
临时回复频道
转换为
字符串

当客户端WebSocket应用程序向会话发送确认时,必须确保使用
replyChannel
返回这些请求头。在Spring集成的这一边,一切都应该是透明的

如果我错过了什么,请告诉我

更新


好。谢谢你提供更多信息!你的配置看起来不错。几点意见:一,。无需使用
reply channel=“lightOnResponse”
:HTTP入站网关非常好地等待来自
临时reply频道的回复。2.请在转发到WebSocket之前,将
添加到您的
。3.
只需将其入站消息发送到简单的
网桥
。在这种情况下,如果没有
output channel
,它将消息从标题委托给
replyChannel
。因此,您的HTTP入站网关将收到适当的答复。

Hi Artem。谢谢你的回复。我所有的开发都是基于Spring集成的,这意味着Websocket是基于Spring集成适配器的。从您的回复中,我现在了解了如何选择websocket客户端(基于SESSION\u ID\u头),我将能够转发到正确的客户端。但我不明白,如何将websocket响应作为REST响应自动转发。我会在下面发送一段代码,希望你能再次发表评论。
<!-- 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"/>