问题描述
我想创建一个 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 适配器,你有 ServerWebSocketContainer
有 getSessions()
返回 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 网关连接起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!