本文介绍了Spring 集成将入站 HTTP 网关与出站 Websocket 网关连接起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a REST service to turn on the light. The architecture that I want to have is the following:

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

我想使用 Spring Integration 框架来实现这一点.我在想这样的事情:

I would like to accomplish this using Spring Integration framework. I was thinking of something like:

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

Request : Inbound HTTP GW -> Outbound Websocket GW

响应:入站 HTTP GW

Response: Inbound HTTP GW <- Inbound Websocket GW

问题是我不知道如何指定websocket客户端.知道怎么做吗?

The problem is that I don't know how to specify the websocket client. Any idea how to do it ?

目前,根据我收到的答案,这是提供解决方案的伪代码:

For now, and based on the answers I have received this is the pseudo-code that provides the solution:

<!-- 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 适配器,你有 ServerWebSocketContainergetSessions() 返回 Map连接的客户端会话.因此,您可以通过 REST 服务向最终用户公开.

Unfortunately, your question isn't clear. If your WebSocket stuff is based on the Spring Integration WEbSocket adapters, you have ServerWebSocketContainer which has getSessions() to return Map<String, WebSocketSession> of connected client sessions. Hence you can expose to end-users via REST service.

当客户端选择一个会话并发送 HTTP 请求时,您可以简单地将带有 SimpMessageHeaderAccessor.SESSION_ID_HEADER 的消息转发到 .

When the client select one session and send an HTTP request you can simply forward that message with the SimpMessageHeaderAccessor.SESSION_ID_HEADER to the <int-websocket:outbound-channel-adapter>.

是的,您可以使用 接收确认并将其自动转发到 REST 响应.但要实现这一点,您应该使用 TemporaryReplyChannel 转换为 String-channels-to-string> on .

And yes, you can receive an acknowledgement using <int-websocket:inbound-channel-adapter> and forward it to the REST response automatically. But to achieve that you should convert TemporaryReplyChannel from the <int-http:inbound-gateway> to String using <header-channels-to-string> on <header-enricher>.

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

You Client WebSocket application must ensure to return those request headers with the replyChannel, when it send acknowledgement to the session. With Spring Integration on that side everything should be transparent.

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

Let me know if I have missed something.

更新

好.感谢您提供更多信息!你的配置看起来不错.一些说明: 1. 不需要reply-channel="lightOnResponse":HTTP Inbound Gateway 很好地等待来自TemporaryReplyChannel 的回复.2. 请在转发到 WebSocket 之前将 添加到您的 .3. 可以将其入站消息发送到简单的bridge:.在没有 output-channel 的情况下,它将消息从标头委托给 replyChannel.因此,您的 HTTP 入站网关将收到适当的回复.

Good. Thanks for more info! Your config looks good. Some remarks: 1. No need to have reply-channel="lightOnResponse": HTTP Inbound Gateway waits for the reply from the TemporaryReplyChannel very well. 2. Please, add <header-channels-to-string> to your <header-enricher> before forwarding to the WebSocket. 3. The <int-websocket:inbound-channel-adapter> can just sends its inbound message to the simple bridge: <bridge input-channel="lightOnClientResponse">. In this case without output-channel it delegate message to the replyChannel from headers. Hence your HTTP Inbound Gateway will receive appropriate reply.

这篇关于Spring 集成将入站 HTTP 网关与出站 Websocket 网关连接起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 09:40