Spring Boot Web Flux with JOOQ for interfacing with DB and Kotlin coroutines to make blocking JDBC calls run asynchronously. Now with rsockets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

75 lines
2.6 KiB

package com.example.demo.controller
import com.example.demo.model.Message
import io.vavr.collection.HashMap
import io.vavr.collection.Map
import kotlinx.coroutines.delay
import org.slf4j.LoggerFactory
import org.springframework.messaging.handler.annotation.MessageExceptionHandler
import org.springframework.messaging.handler.annotation.MessageMapping
import org.springframework.messaging.rsocket.RSocketRequester
import org.springframework.messaging.rsocket.annotation.ConnectMapping
import org.springframework.stereotype.Controller
import org.springframework.util.MimeType
@Controller
class RSocketConnectionController {
private val log = LoggerFactory.getLogger(RSocketConnectionController::class.java)
private var requesterMap: Map<String, RSocketRequester> = HashMap.empty()
@Synchronized
private fun getRequesterMap(): Map<String, RSocketRequester> {
return requesterMap
}
@Synchronized
private fun addRequester(rSocketRequester: RSocketRequester, clientId: String) {
log.info("adding requester {}", clientId)
requesterMap = requesterMap.put(clientId, rSocketRequester)
}
@Synchronized
private fun removeRequester(clientId: String) {
log.info("removing requester {}", clientId)
requesterMap = requesterMap.remove(clientId)
}
@ConnectMapping("client-id")
fun onConnect(rSocketRequester: RSocketRequester, clientId: String) {
val clientIdFixed = clientId.replace("\"", "") //check why the serializer adds " to strings
// rSocketRequester.rsocket().dispose() //to reject connection
rSocketRequester
.rsocket()
.onClose()
.subscribe(null, null, {
log.info("{} just disconnected", clientIdFixed)
removeRequester(clientIdFixed)
})
addRequester(rSocketRequester, clientIdFixed)
}
@MessageMapping("private.news")
fun privateNews(message: Message, rSocketRequesterParam: RSocketRequester) {
getRequesterMap()
.filterKeys { key -> key == message.toUser || key == message.fromUser }
.values()
.forEach { requester -> sendMessage(requester, message) }
}
@MessageExceptionHandler
suspend fun handleException(ex: IllegalArgumentException): String {
delay(10)
return "${ex.message} handled"
}
private fun sendMessage(requester: RSocketRequester, message: Message) =
requester
.route("user.queue.reply")
.data(message)
.send()
.subscribe()
}