将入站HTTP网关与出站Websocket门户连接的Spring集成

时间:2015-03-16 09:51:13

标签: spring-integration spring-websocket

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

  • 许多嵌入式系统都连接到一个灯光实例
  • 每个嵌入式系统都有一个websocket客户端,连接到我的服务器
  • 我的服务器拥有一项REST服务,允许网络客户端选择一个光照实例,并将其打开
  • REST服务将有一个参数来指定一个灯光实例的引用,连接到系统并将消息发送到websocket客户端,等待来自客户端的确认消息,然后返回REST答案

我想使用Spring Integration框架来实现这一目标。我想的是:

请求:入站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"/>

1 个答案:

答案 0 :(得分:2)

不幸的是,你的问题不明确。如果您的WebSocket内容基于Spring Integration WEbSocket适配器,那么ServerWebSocketContainer getSessions()可以返回Map<String, WebSocketSession>连接的客户端会话。因此,您可以通过REST服务向最终用户公开。

当客户选择一个会话并发送HTTP请求时,您只需使用SimpMessageHeaderAccessor.SESSION_ID_HEADER将该消息转发到<int-websocket:outbound-channel-adapter>即可。

是的,您可以使用<int-websocket:inbound-channel-adapter>收到确认并自动将其转发给REST响应。但要实现这一点,您应该使用TemporaryReplyChannel上的<int-http:inbound-gateway>String<header-channels-to-string>转换为<header-enricher>

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

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

<强>更新

好。感谢您提供更多信息!你的配置看起来不错。一些评论:1。无需reply-channel="lightOnResponse":HTTP Inbound Gateway非常好地等待来自TemporaryReplyChannel的回复。 2.在转发到WebSocket之前,请将<header-channels-to-string>添加到<header-enricher>。 3. <int-websocket:inbound-channel-adapter>只能将其入站邮件发送到简单bridge<bridge input-channel="lightOnClientResponse">。在没有output-channel的情况下,它会从标头中将消息委托给replyChannel。因此,您的HTTP入站网关将收到适当的回复。