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.
|
|
package com.example.demo.controller
import com.example.demo.model.Message import com.example.demo.model.User import io.vavr.collection.HashMap import io.vavr.collection.Map import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import org.slf4j.LoggerFactory import org.springframework.messaging.handler.annotation.MessageExceptionHandler import org.springframework.messaging.handler.annotation.MessageMapping import org.springframework.messaging.handler.annotation.Payload import org.springframework.messaging.rsocket.RSocketRequester import org.springframework.messaging.rsocket.annotation.ConnectMapping import org.springframework.stereotype.Controller
@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, @Payload user: User) { // val clientIdFixed = clientId.replace("\"", "") //check why the serializer adds " to strings
// rSocketRequester.rsocket().dispose() //to reject connection
val clientId = user.id.toString() rSocketRequester .rsocket() .onClose() .subscribe(null, null, { log.info("{} just disconnected", clientId) removeRequester(clientId) }) addRequester(rSocketRequester, clientId) }
@MessageMapping("private.news") fun privateNews(message: Message, rSocketRequesterParam: RSocketRequester) { getRequesterMap() .filterKeys { key -> key == message.toUser || key == message.fromUser } .values() .forEach { requester -> run { println("Sending message") sendMessage(requester, message) } }
}
@MessageExceptionHandler suspend fun handleException(ex: IllegalArgumentException): String { delay(10) return "${ex.message} handled" }
@MessageMapping("echo-stream-async") suspend fun echoStreamAsync(payload: String): Flow<String> { delay(10) var i = 0 return flow { while (true) { delay(10) emit("$payload ${i++}") } } }
private fun sendMessage(requester: RSocketRequester, message: Message) = requester .route("user.queue.reply") // .metadata("test", MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_COMPOSITE_METADATA.string))
.data(message) .send() .subscribe()
}
|