【发布时间】:2014-08-06 20:01:29
【问题描述】:
我的应用列出了主机,并且该列表是动态且不断变化的。它基于 Akka 演员和服务器发送事件。 当新客户端连接时,他们需要获取当前列表以显示。但是,我不想每次连接新客户端时都将列表推送给所有客户端。因此,遵循实时弹性搜索示例并通过为每个 Connect() 创建一个 (Enumerator, Channel) 并为其提供 UUID 来模拟单播。当我需要广播时,我将映射所有内容并更新它们,以便能够向客户端进行单播(并且应该很少)。
我的问题是 - 我如何获得新客户端的 UUID 以便它可以使用它?我正在寻找的流程是: - 客户要求 EventStream - 服务器用 UUID 创建一个新的(Enumerator, channel),并将 Enumerator 和 UUID 返回给客户端 - 客户使用 uuid 请求表格 - 服务器只在对应 uuid 的通道上推送表
那么,客户端如何知道 UUID?如果是 Web 套接字,发送请求应该会得到预期的结果,因为它会到达自己的通道。但在 SSE 中,客户端 -> 服务器是在不同的通道上完成的。有什么解决办法吗?
代码 sn-ps:
case class Connected(uuid: UUID, enumerator: Enumerator[ JsValue ] )
trait MyActor extends Actor{
var channelMap = new HashMap[UUID,(Enumerator[JsValue], Channel[JsValue])]
def connect() = {
val con = Concurrent.broadcast[JsValue]
val uuid = UUID.randomUUID()
channelMap += (uuid -> con)
Connected(uuid, con._1)
}
...
}
object HostsActor extends MyActor {
...
override def receive = {
case Connect => {
sender ! connect
}
...
}
object Actors {
def hostsStream = {
getStream(getActor("hosts", Props (HostsActor)))
}
def getActor(actorPath: String, actorProps : Props): Future[ActorRef] = {
/* some regular code to create a new actor if the path does not exist, or return the existing one else */
}
def getStream(far: Future[ActorRef]) = {
far flatMap {ar =>
(ar ? Connect).mapTo[Connected].map { stream =>
stream
}
}
}
...
}
object AppController extends Controller {
def getHostsStream = Action.async {
Actors.hostsStream map { ac =>
************************************
** how do i use the UUID here?? **
************************************
Ok.feed(ac.enumerator &> EventSource()).as("text/event-stream")
}
}
【问题讨论】:
标签: scala playframework-2.0 akka actor server-sent-events