Closed mdddj closed 2 years ago
Hi, thank you for your question.
If you check the stacktrace of the error, you can see multiple Caused by
lines. The last one that appears is the root cause of the error. In this case, it reads Engine doesn't support WebSocketCapability
. This means the Ktor engine you're using doesn't support web sockets. Which Ktor engine do you use?
You can check which engines support web sockets here: https://ktor.io/docs/http-client-engines.html#limitations
@joffrey-bion Hi, thank you for your reply. I checked the document, but an exception occurred
Modified code
val okHttpClient = OkHttpClient.Builder()
.callTimeout(Duration.ofMinutes(1))
.pingInterval(Duration.ofSeconds(10))
.build()
val wsClient = OkHttpWebSocketClient(okHttpClient)
val stompClient = StompClient(wsClient)
try{
val session = stompClient.connect("ws://192.168.199.86/idea-chat?token=${tokenField.text}")
val subscribeText = session.subscribeText("/room/闲聊吹水")
launch {
subscribeText.collect {msg -> println("收到消息:$msg") }
}
}catch (e: StompConnectionException) {
println("Error:$e ")
}
error message
Error:org.hildan.krossbow.stomp.StompConnectionException: Failed to connect at STOMP protocol level to host '192.168.199.86'
My local service has been started and can receive connections, but the client cannot connect
Error:org.hildan.krossbow.stomp.StompConnectionException: Failed to connect at STOMP protocol level to host '192.168.199.86'
at org.hildan.krossbow.stomp.StompWsExtensionsKt.stomp(StompWsExtensions.kt:36)
at org.hildan.krossbow.stomp.StompWsExtensionsKt$stomp$1.invokeSuspend(StompWsExtensions.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:33)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:102)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:33)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:102)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Caused by: java.lang.IllegalStateException: Expected CONNECTED frame in response to CONNECT, got Connect(headers=StompConnectHeaders(rawHeaders=SimpleStompHeaders(headers={host=192.168.199.86, accept-version=1.2, heart-beat=0,0})))
at org.hildan.krossbow.stomp.StompWsExtensionsKt.awaitConnectedFrame(StompWsExtensions.kt:58)
at org.hildan.krossbow.stomp.StompWsExtensionsKt.access$awaitConnectedFrame(StompWsExtensions.kt:1)
at org.hildan.krossbow.stomp.StompWsExtensionsKt$awaitConnectedFrame$1.invokeSuspend(StompWsExtensions.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
... 4 more
This is strange. According to the error, the server replied CONNECT
instead of CONNECTED
.
Do you have other code to share from the server side? Could it be that some websocket handler code is echoing the frames back to the client?
Yes, I think there is a problem on the server. I am looking for a solution
@Resource
private lateinit var connectErrorHandle: ConnectErrorHandle
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
super.registerStompEndpoints(registry)
registry.addEndpoint("/idea-chat")
.setAllowedOrigins("*")
.setHandshakeHandler(principalHandshakeHandle)
.addInterceptors(jwtVaildInterceptor)
registry.setErrorHandler(connectErrorHandle)
}
@Component
class ConnectErrorHandle : StompSubProtocolErrorHandler() {
private var log = LoggerFactory.getLogger(ConnectErrorHandle::class.java)
override fun handleClientMessageProcessingError(
clientMessage: Message<ByteArray>?,
ex: Throwable
): Message<ByteArray>? {
// clientMessage?.let {
// return ErrorResultMessage(clientMessage,ex)
// }
log.error("error: ${ex}")
return super.handleClientMessageProcessingError(clientMessage, ex)
}
}
The error code
2022-11-04T17:11:23.073+08:00 ERROR 92662 --- [p-nio-80-exec-1] s.i.t.i.w.socket.v1.ConnectErrorHandle : error: org.springframework.messaging.MessageDeliveryException: Failed to send message to ExecutorSubscribableChannel[clientInboundChannel], failedMessage=GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={host=[192.168.199.86], accept-version=[1.2], heart-beat=[0,0]}, simpSessionAttributes={user=shop.itbug.ticket.idea.web.socket.v1.JwtVaildInterceptor$$Lambda$1957/0x0000000801812ff0@ec4ad95}, simpHeartbeat=[J@291659c7, simpUser=shop.itbug.ticket.idea.web.socket.v1.JwtVaildInterceptor$$Lambda$1957/0x0000000801812ff0@ec4ad95, simpSessionId=be89781b-4b81-034a-e701-e4038d4e32b3}]
2022-11-04T17:11:23.081+08:00 WARN 92662 --- [p-nio-80-exec-1] w.s.h.ExceptionWebSocketHandlerDecorator : Unhandled exception after connection closed for ExceptionWebSocketHandlerDecorator [delegate=LoggingWebSocketHandlerDecorator [delegate= [delegate=SubProtocolWebSocketHandler[StompSubProtocolHandler[v10.stomp, v11.stomp, v12.stomp]]]]]
log.error("error: ${ex}")
note that you can use the overload of .error()
that takes an exception as argument, so you can see the full stacktrace in the logs: log.error("websocket connection error", ex)
.
At the moment it's hard to tell what the root cause of the error is without the full stacktrace
Thanks, I got the following error, but I still failed after disabling csrf
Caused by: org.springframework.security.web.csrf.MissingCsrfTokenException: Could not verify the provided CSRF token because no token was found to compare.
at org.springframework.security.messaging.web.csrf.CsrfChannelInterceptor.preSend(CsrfChannelInterceptor.java:53) ~[spring-security-messaging-6.0.0-M7.jar:6.0.0-M7]
at org.springframework.messaging.support.AbstractMessageChannel$ChannelInterceptorChain.applyPreSend(AbstractMessageChannel.java:181) ~[spring-messaging-6.0.0-M6.jar:6.0.0-M6]
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:135) ~[spring-messaging-6.0.0-M6.jar:6.0.0-M6]
... 28 common frames omitted
Thank you for your help. I found a solution to the problem. Deleting the @ EnableWebSocketSecurity annotation in Springboot3.0 will solve the problem
https://docs.spring.io/spring-security/reference/6.0/servlet/integrations/websocket.html
Glad that you found the problem!
springboot config
krossbow
error log
I'm a novice. It's boring. I can't connect it with anything
my code repository https://github.com/mdddj/json_to_dart_pro/blob/ab5e947ea6612358ac84b2a15449f8fe4cbb1ccd/src/main/kotlin/windown/ChatWindow.kt#L49