[英]How to make sure the previous session.send() is complete before sending more data in reactor-netty WebSocketSession
I am creating a WebSocket Server using spring-webflux and reactor.netty, and on every connection, I get a WebSocketSession (with ReactorNettyWebSocketSession instance).我正在使用 spring-webflux 和 reactor.netty 创建一个 WebSocket 服务器,并且在每个连接上,我都会得到一个 WebSocketSession(带有 ReactorNettyWebSocketSession 实例)。 Suppose I store all the sessions in a map and want to send some messages to this WebSocketSessions based on some business logic, I can do something like
假设我将所有会话存储在 map 中,并希望根据某些业务逻辑向此 WebSocketSessions 发送一些消息,我可以做类似的事情
Flux<String> stringFlux = Flux.fromIterable(messages);
for (WebSocketSession session : sessions.values()) {
if (session.isOpen()) {
session
.send(stringFlux.map(session::textMessage))
.subscribe();
} else {
System.out.println("session is closed.. skipping.. " + session.getId());
sessions.remove(session.getId());
}
}
Now, when I send messages to the session, is there a way to make sure that the session's previous send is complete?现在,当我向 session 发送消息时,有没有办法确保会话的上一次发送已完成? If a client is very slow and/or not reading from the server, it can create memory overhead for the server if the server keeps writing to the socket when the client is not reading or reading very slowly.
如果客户端非常慢和/或不从服务器读取,如果服务器在客户端不读取或读取速度非常慢时继续写入套接字,则可能会为服务器创建 memory 开销。
How to get a callback or some mechanism in which I can prevent writing to the WebSocketSession/socket if the client is slow?如果客户端速度很慢,如何获得回调或某种机制来阻止写入 WebSocketSession/socket?
There are quite a lot of assumptions behind this answer so we might need to discuss the details in the comments.这个答案背后有很多假设,所以我们可能需要在评论中讨论细节。 The idea is that the following code sends messages one by one for each session, but concurrently for all sessions.
这个想法是,以下代码为每个 session 一个接一个地发送消息,但同时为所有会话发送消息。 You can tweak this according to your needs, turning
concatMap
to flatMap
will enable concurrent sending while turning flatMap
to concatMap
will ensure that all all messages have to be sent to a single session before moving on to the next one.您可以根据您的需要进行调整,将
concatMap
为flatMap
将启用并发发送,而将flatMap
转换为concatMap
将确保所有消息都必须发送到一个 session,然后才能继续发送到下一个消息。
Flux.fromIterable(sessions.values())
.filter(session -> session.isOpen()) // keep open sessions
.doOnDsicard(Session.class, session -> {
System.out.println("session is closed.. skipping.. " + session.getId());
sessions.remove(session.getId());
})
// flatMap here will allow the messages to be sent to each session concurrently
.flatMap(session -> Flux.fromIterable(messages)
.map(session::textMessage)
// concatMap here will force messages to be sent one by one (per session)
.concatMap(message -> Mono
.fromCallable(() -> session
.send(Mono.just(message))), 0))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.