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.
86 lines
2.9 KiB
86 lines
2.9 KiB
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"
|
|
}
|
|
|
|
}
|