我正在使用
Quarkus
,几年后再次尝试配置 WS 客户端,但我正在努力寻找解决方案。
BoM 3.7.1 版本中的相关依赖项
配置我的
@ClientEndpoint
并启动 Websocket 客户端:
ContainerProvider.getWebSocketContainer().connectToServer(RomanWebsocketClient::class.java, URI)
我有 2 个结果。
wss://socketsbay.com/wss/v2/1/demo/
(这只是为了测试配置)https://myserverdomain/await/some-url-encoded-token
(这就是我想要的)第二个给了我一个308永久重定向我不得不说在基于ktor的BE中使用相同的URI是可行的,所以我认为我缺少一些额外的配置,比如升级等等。
我尝试过的:
ClientEndpointConfig.Configurator
来注入标头
(“连接”、“升级”等)但不起作用。application.properties
配置,如 followRedirects
,也不起作用,我认为这可能是无关的。我想知道什么:
好吧,最后我没有找到解决方案,而是找到了一种解决方法,以防万一有人感兴趣,我所做的只是使用
java.net.http.WebSocket
,因为从 Java 11 开始有更好的 API。
我实现了
WebSocket.Listener
接口,并在我的例子中将 Client 定义为在启动时急切注册的 Bean。
@ApplicationScoped
@Startup
class WebsocketClient(
@ConfigProperty(name = "quarkus.rest-client.api.url")
private val baseUrl: String,
@ConfigProperty(name = "quarkus.rest-client.api.key")
private val apiKey: String
) : WebSocket.Listener {
private val logger = LoggerFactory.getLogger(this::class.java)
private val executorService: ExecutorService = Executors.newFixedThreadPool(5)
private val httpClient: HttpClient = HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.ALWAYS)
.executor(executorService)
.build()
private val wsUri = run {
URI(baseUrl) // in case is an https schema, replace it to wss, since internally gets converted to https in
.resolve("/await/" + URLEncoder.encode(apiKey, "utf-8"))
}
@PostConstruct
fun init() {
httpClient.newWebSocketBuilder()
.buildAsync(wsUri, this)
.join()
}
override fun onOpen(webSocket: WebSocket?) {
super.onOpen(webSocket)
}
override fun onText(webSocket: WebSocket?, data: CharSequence?, last: Boolean): CompletionStage<*> {
super.onText(webSocket, data, last)
logger.info("Message received raw: $data")
// process data...
return CompletableFuture<Void>()
}
override fun onClose(webSocket: WebSocket?, statusCode: Int, reason: String?): CompletionStage<*> {
super.onClose(webSocket, statusCode, reason)
logger.info(">> Websocket close: ${reason ?: "no reason"}, reopening...")
init()
return CompletableFuture<Void>().also { it.complete(null) }
}
override fun onError(webSocket: WebSocket?, error: Throwable?) {
super.onError(webSocket, error)
logger.info(">> Websocket error: ${error?.message}, reopening...")
init()
}
}
我希望在某个时候能够使用 Quarkus Websocket 客户端,但现在,这解决了我遇到的架构问题,我可以继续前进。