gpt4 book ai didi

scala - 我可以将单个 Play WebSocket 用于广播和私有(private)消息吗?

转载 作者:行者123 更新时间:2023-12-02 00:05:21 25 4
gpt4 key购买 nike

我需要向我当前正在为其处理 Play WebSocket 消息的客户端发送私有(private)响应,而对于其他消息,我需要向所有客户端广播响应。

在 Play 聊天示例中,传入消息 are immediately offloaded to a single Actor :

case Connected(enumerator) => 
// Create an Iteratee to consume the feed, assuming all requests have
// a JSON "text" node, and delegate all to the Akka Actor:
val iteratee = Iteratee.foreach[JsValue] { event =>
default ! Talk(username, (event \ "text").as[String])
}.map { _ =>
default ! Quit(username)
}
(iteratee,enumerator)

上面,一旦连接被批准 enumerator 被传回,它指的是已经由同一个 Actor 创建的单个 chatEnumerator:

val (chatEnumerator, chatChannel) = Concurrent.broadcast[JsValue]

我假设这不允许我只向单个客户端发送消息?我应该删除广播功能并为每个客户端创建和跟踪枚举器,然后自己进行迭代吗?或者我能否以某种方式获得对 foreach 中特定于客户端的枚举器的引用?

(我知道内置的灵 active depends on the implementation ,但这个用例对我来说似乎很常见。就像将 WebSockets 与 Socket.IO 一起使用时,我可以轻松地发送消息 to either 所有客户端,除了发件人之外的所有客户端当前请求的一部分,或者只是一个客户端。这也是我在 Play 2.1.x 中想要实现的。)

最佳答案

一种方法是使用 Enumerator.interleave 交错两个枚举器.

因此,您可以使用Concurrent.broadcast 两次创建两对(Enumerator, Channel),一对用于广播,另一对用于私有(private)连接,并将其交错。(或者可能只使用 Concurrent.unicast 作为私有(private)枚举器,但我不知道如何使用它。)

这是一些适用于 play 2.3.0 的示例 Play 代码。

object Application extends Controller {
val (publicOut,publicChannel) = Concurrent.broadcast[String]
def chat = WebSocket.using[String]{ request =>
val (privateOut,privateChannel) = Concurrent.broadcast[String]
val in = Iteratee.foreach{
msg:String => if(msg.startsWith("@")){
publicChannel.push("Broadcasted: " + msg)
}else{
privateChannel.push("Private: " + msg)
}
}
val out = Enumerator.interleave(publicOut,privateOut)
(in, out)
}
}

向特定客户端发送消息的代码会有点复杂,但概念是一样的。创建一个 Actor,每个 websocket 包含一对 (Enumerator, Channel) 并向 actor 发送消息。

关于scala - 我可以将单个 Play WebSocket 用于广播和私有(private)消息吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18751792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com