我在使用Websaut 3.9.0中的WebSocket连接时遇到问题。我正在尝试为WebSocket连接设置超时,尽管我进行了努力,超时似乎没有按预期中断连接尝试。
我尝试在Flux对象上使用超时操作符,但它似乎并不像我想象的那样工作。连接尝试继续超过指定的超时。
示例代码:
package com.example;
import io.micronaut.context.BeanContext;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import io.micronaut.websocket.WebSocketClient;
import io.micronaut.websocket.WebSocketSession;
import io.micronaut.websocket.annotation.ClientWebSocket;
import io.micronaut.websocket.annotation.OnClose;
import io.micronaut.websocket.annotation.OnMessage;
import io.micronaut.websocket.annotation.OnOpen;
import lombok.extern.slf4j.Slf4j;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import jakarta.inject.Inject;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
@Slf4j
@MicronautTest
class WstimeoutTest {
static AtomicBoolean isOpened = new AtomicBoolean(false);
@Inject
BeanContext beanContext;
@ClientWebSocket
static abstract class TestWebSocketClient implements AutoCloseable {
@OnMessage
void onMessage(String message) {
log.info("[onMessage] Got message: {}", message);
}
@OnOpen
void onOpen(WebSocketSession session) {
log.info("[onOpen] WS session id: {}", session.getId());
isOpened.set(true);
}
@OnClose
void onClose(WebSocketSession session) {
log.info("[onClose] WS session id: {}", session.getId());
}
}
@Test
void testWebSocketTimeout() {
var uri = "ws://localhost";
var timeout = Duration.ofMillis(40); //Put here the time that ws client is unable to establish (or emit OnOpen event) websocket connection
var webSocketClient = beanContext.getBean(WebSocketClient.class);
Publisher<TestWebSocketClient> client = webSocketClient.connect(TestWebSocketClient.class, uri);
Flux.from(client)
.timeout(timeout)
.doOnError(throwable -> log.info("Expected error: {}", throwable.getMessage()))
.subscribe();
Awaitility.await().atLeast(Duration.ofMillis(250)).untilAsserted(
() -> Assertions.assertFalse(isOpened.get(), "WebSocket should not be opened")
);
}
}
字符串
测试输出:
2023:11:21T13:24:56.140 [parallel-1] INFO com.example.WstimeoutTest[][] - Expected error: Did not observe any item or terminal signal within 40ms in 'switchMapNoPrefetch' (and no fallback has been configured)
2023:11:21T13:24:56.178 [default-nioEventLoopGroup-1-2] INFO com.example.WstimeoutTest[][] - [onOpen] WS session id: AOKppbvUUl5zc3/x1N0lBiXW4WU=
WebSocket should not be opened
Expected :false
Actual :true
型
有什么方法可以正确地使WebSocket连接超时吗?
2条答案
按热度按时间pbpqsu0x1#
您正在Assert
onClose()
方法中未更改的值:字符串
olhwl3o22#
我相信我已经找到了一个解决方案后,研究和实验
HttpClientConfiguration
.该解决方案涉及设置ConnectTimeout
的HttpClient:)此外,在连接到localhost的情况下,时间限制可能会被忽略,因为通信发生在相同的环境中(?)(至少下面的代码失败,即使我为本地服务器设置
httpTimeout = Duration.ofNanos(1)
)。为了测试这一点,我使用了在线echo WebSocket服务器。下面是完整的示例代码沿着我的结果:字符串
输出量:
型
似乎没有特定的
TimeoutException
,而是一个WebSocketClientException
,其中包含有关Abnormal Closure
的信息。此外,没有触发WS事件,如预期的onOpen
、onMessage
、onClose
或onError
。