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.

74 lines
2.6 KiB

  1. package com.example.demo.controller
  2. import com.example.demo.model.Message
  3. import io.vavr.collection.HashMap
  4. import io.vavr.collection.Map
  5. import kotlinx.coroutines.delay
  6. import org.slf4j.LoggerFactory
  7. import org.springframework.messaging.handler.annotation.MessageExceptionHandler
  8. import org.springframework.messaging.handler.annotation.MessageMapping
  9. import org.springframework.messaging.rsocket.RSocketRequester
  10. import org.springframework.messaging.rsocket.annotation.ConnectMapping
  11. import org.springframework.stereotype.Controller
  12. import org.springframework.util.MimeType
  13. @Controller
  14. class RSocketConnectionController {
  15. private val log = LoggerFactory.getLogger(RSocketConnectionController::class.java)
  16. private var requesterMap: Map<String, RSocketRequester> = HashMap.empty()
  17. @Synchronized
  18. private fun getRequesterMap(): Map<String, RSocketRequester> {
  19. return requesterMap
  20. }
  21. @Synchronized
  22. private fun addRequester(rSocketRequester: RSocketRequester, clientId: String) {
  23. log.info("adding requester {}", clientId)
  24. requesterMap = requesterMap.put(clientId, rSocketRequester)
  25. }
  26. @Synchronized
  27. private fun removeRequester(clientId: String) {
  28. log.info("removing requester {}", clientId)
  29. requesterMap = requesterMap.remove(clientId)
  30. }
  31. @ConnectMapping("client-id")
  32. fun onConnect(rSocketRequester: RSocketRequester, clientId: String) {
  33. val clientIdFixed = clientId.replace("\"", "") //check why the serializer adds " to strings
  34. // rSocketRequester.rsocket().dispose() //to reject connection
  35. rSocketRequester
  36. .rsocket()
  37. .onClose()
  38. .subscribe(null, null, {
  39. log.info("{} just disconnected", clientIdFixed)
  40. removeRequester(clientIdFixed)
  41. })
  42. addRequester(rSocketRequester, clientIdFixed)
  43. }
  44. @MessageMapping("private.news")
  45. fun privateNews(message: Message, rSocketRequesterParam: RSocketRequester) {
  46. getRequesterMap()
  47. .filterKeys { key -> key == message.toUser || key == message.fromUser }
  48. .values()
  49. .forEach { requester -> sendMessage(requester, message) }
  50. }
  51. @MessageExceptionHandler
  52. suspend fun handleException(ex: IllegalArgumentException): String {
  53. delay(10)
  54. return "${ex.message} handled"
  55. }
  56. private fun sendMessage(requester: RSocketRequester, message: Message) =
  57. requester
  58. .route("user.queue.reply")
  59. .data(message)
  60. .send()
  61. .subscribe()
  62. }