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 kotlinx.coroutines.* import org.slf4j.LoggerFactory 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 import io.vavr.collection.Map import org.springframework.messaging.handler.annotation.MessageExceptionHandler
@Controller class RsocketConnectionControllerAsync : CoroutineScope { private val log = LoggerFactory.getLogger(RsocketConnectionControllerAsync::class.java) private val job = Job() override val coroutineContext = Dispatchers.Unconfined + job
@ObsoleteCoroutinesApi private val myRsocketActor = rsocketActor()
@ObsoleteCoroutinesApi suspend fun addRequester(rSocketRequester: RSocketRequester, clientId: String) { log.info("adding requester {}", clientId) myRsocketActor.send(AddRequester(rSocketRequester, clientId)) }
@ObsoleteCoroutinesApi suspend fun removeRequester(clientId: String) { log.info("removing requester {}", clientId) myRsocketActor.send(RemoveRequester(clientId)) }
@ObsoleteCoroutinesApi @ConnectMapping(value = ["client-id2"]) fun onConnect( rSocketRequester: RSocketRequester, @Payload user: User ) { launch(coroutineContext) { val clientId = user.id.toString() addRequester(rSocketRequester, clientId) rSocketRequester .rsocket() .onClose() .subscribe(null, null, { log.info("{} just disconnected", clientId) launch(coroutineContext) { removeRequester(clientId) } })
} }
@ObsoleteCoroutinesApi @MessageMapping("private.news.2") fun privateNews(message: Message) { launch { val res = CompletableDeferred<Map<String, RSocketRequester>>() myRsocketActor.send(GetRequesters(res)) res .await() .filterKeys { key -> key == message.toUser || key == message.fromUser } .values() .forEach { requester -> println("Sending message") sendMessage(requester, message) } } }
private fun sendMessage(requester: RSocketRequester, message: Message) = requester .route("user.queue.reply") .data(message) .send() .subscribe()
@MessageExceptionHandler suspend fun handleException(ex: IllegalArgumentException): String { delay(10) return "${ex.message} handled" }
}
|