-
Notifications
You must be signed in to change notification settings - Fork 42
Description
Description
When using ktor-client-rsocket (version 0.20.0) to connect to a Spring Boot 4.0.0 RSocket server, the routing metadata is not being properly recognized by the server, resulting in the error:
io.rsocket.kotlin.RSocketError$ApplicationError: No handler for destination ''
The empty string in the error message indicates that the routing metadata is either not being sent or not being decoded properly by the Spring Boot server.
Environment
Client:
- rsocket-kotlin version: 0.20.0
- ktor-client-rsocket version: 0.20.0
- Kotlin version: 2.2.21
- Ktor version: 3.3.3
- JVM: 24
Server:
- Spring Boot version: 4.0.0
- spring-boot-starter-rsocket
- Transport: WebSocket
- Endpoint:
ws://localhost:9000/rsocket
Expected Behavior
The client should successfully send routing metadata that Spring Boot's @MessageMapping can recognize and route to the appropriate handler.
Actual Behavior
Spring Boot server receives an empty destination string, causing routing to fail with:
io.rsocket.kotlin.RSocketError$ApplicationError: No handler for destination ''
Code to Reproduce
Spring Boot Server (Working)
@Controller
class RSocketController {
@MessageMapping("salam")
suspend fun salam(@Payload(required = true) name: String?): String {
delay(1000)
val actualName = name ?: "unknown"
return "Hello, $actualName!"
}
}application.yml:
spring:
rsocket:
server:
port: 9000
transport: websocket
mapping-path: /rsocketClient Code (Not Working)
Attempt 1: Using metadata() with RoutingMetadata
val rsocket = client.rSocket("ws://localhost:9000/rsocket")
val payload = buildPayload {
data("halim")
metadata(RoutingMetadata("salam"))
}
val response = rsocket.requestResponse(payload)
// Error: No handler for destination ''Attempt 2: Using compositeMetadata with RoutingMetadata constructor
val payload = buildPayload {
data("halim")
compositeMetadata {
add(RoutingMetadata(tags = listOf("salam")))
}
}
// Error: No handler for destination ''Attempt 3: Using compositeMetadata with RoutingMetadata builder
val payload = buildPayload {
data("halim")
compositeMetadata {
add(RoutingMetadata {
+"salam" // unary plus operator
})
}
}
// Error: No handler for destination ''Attempt 4: Using route() in builder
val payload = buildPayload {
data("halim")
compositeMetadata {
add(RoutingMetadata {
route("salam")
})
}
}
// Error: No handler for destination ''All attempts result in the same error.
Workaround
Switching to Spring's RSocketRequester (Java/Reactor-based client) works perfectly:
val requester = RSocketRequester.builder()
.websocket(URI.create("ws://localhost:9000/rsocket"))
val response = requester
.route("salam")
.data("halim")
.retrieveMono(String::class.java)
.awaitSingle()
// Works! Response: "Hello, halim!"Analysis
This suggests that:
- The routing metadata encoding in rsocket-kotlin 0.20.0 may not be compatible with Spring Boot 4.0.0's RSocket implementation
- There might be a protocol version mismatch
- The composite metadata format might not match what Spring Boot expects
Questions
- Is rsocket-kotlin 0.20.0 tested against Spring Boot 4.0.0?
- Are there any known compatibility issues with Spring Boot's RSocket implementation?
- Is there a correct way to encode routing metadata that's compatible with Spring Boot?
Additional Context
- The WebSocket connection itself works (no connection errors)
- The error occurs during the request-response interaction
- The same Spring Boot server works perfectly with Spring's RSocketRequester
- This appears to be a metadata encoding/decoding compatibility issue
Related Issues
Similar issue reported in: https://stackoverflow.com/questions/68778681/rsocket-android-spring-boot-back-end-routing-error-no-handler-for-destination