【问题标题】:Targeting specific Micronaut WebSocket connections针对特定的 Micronaut WebSocket 连接
【发布时间】:2020-04-02 13:40:49
【问题描述】:

我正在尝试创建一个 Kotlin 服务,该服务能够将数据从 Kafka 传递到(特定的)WebSocket 连接。 例如,如果来自用户的数据在 Kafka 上经过,程序会接收到它,如果当前连接的是同一用户,我想将其传递给正确的 WebSocket 连接。

我的基础是:

@KafkaListener()
@Controller
@Secured(SecurityRule.IS_ANONYMOUS)
@ServerWebSocket("/ws/{id}")
class WebSocket() {

    @OnOpen
    fun onOpen(session: WebSocketSession, id: String): Publisher<String> {
        return session.send("connection opened")
    }
}

但是,如果我在同一个班级中收到一条 Kafka 消息,其中包含我正在寻找的用户 ID,我如何将其传递给正确的 WebSocket 连接?

我想如果我使用网址中的"/ws/{id}",我可以轻松地将其发送到正确的 id,但我不知道如何。

我知道向连接发送数据的唯一方法是从 websocket 注释函数内部,如 OnOpen 和 OnMessage 等。 此外,我发现 Micronaut WebSocketBroadcaster 很有用,但当然只用于广播。

我要弄清楚的其他事情是在哪里确保连接的 id 也是用户的实际 id 而不是其他人的,我应该在 @Secured 注释中实现它吗?

【问题讨论】:

    标签: java kotlin websocket micronaut


    【解决方案1】:

    对于任何感兴趣的人,我确实找到了解决方案。 使用 Micronaut WebSocketBroadcaster,您可以广播消息,并使用第二个参数,它采用 Predicate&lt;WebSocketSession&gt;,它定义将消息发送到哪个 WebSocketSession。

    如果您确实知道具体的 WebSocketSession ID,您可以简单地使用 { it.id == "id" } 作为谓词,如示例 1 中所做的那样。 如果您确实需要根据其他属性将其发送给特定用户,您可以使用session.attributes.put("id", id) 将属性分配给 WebSocketSession 本身,例如在 onOpen 函数中。您可以使用的谓词在示例 2 中,唯一的问题是我无法找到一种方法来检索属性而不将其转换为地图,这不是很漂亮。

    class ExampleClass(val broadcaster: WebSocketBroadcaster) {
        val userId = "user_001"
        val webSocketId = "asdasdasd"
    
        // [1] Send message to a specific socket ID
        broadcaster.broadcast("message", { it.id == webSocketId)
    
        // [2] Send message to a user with specific ID or any other identifying attribute of choice
        broadcaster.broadcast("message", { it.attributes.asMap()["id"]?.equals(id) ?: false})    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-01
      • 1970-01-01
      • 2019-03-08
      • 2018-08-07
      • 1970-01-01
      • 2016-11-12
      • 2013-04-23
      • 2021-08-24
      • 1970-01-01
      相关资源
      最近更新 更多