如何在scala中使用WebSocket创建多个聊天室?

如何在scala中使用WebSocket创建多个聊天室?,scala,playframework,websocket,akka,chatroom,Scala,Playframework,Websocket,Akka,Chatroom,我正试图通过Scala剧本中的聊天示例学习如何使用WebSocket和Akka 在书中,有一个“聊天室”正在创建中,它在聊天控制器中被实例化,简单如下: val-room=Akka.system.actorOf(道具[聊天室]) 我想扩展这个示例,并提供多个聊天室,而不是一个聊天室。用户可以提供一个字符串,它可以是聊天室的“名称”,这将创建一个新的聊天室。任何试图加入此聊天室的人都会彼此共享广播,但不会与其他聊天室中的人共享广播。与IRC非常相似 我的问题如下: 1:如果聊天室还不存在,如何创建

我正试图通过Scala剧本中的聊天示例学习如何使用WebSocket和Akka

在书中,有一个“聊天室”正在创建中,它在聊天控制器中被实例化,简单如下:

val-room=Akka.system.actorOf(道具[聊天室])

我想扩展这个示例,并提供多个聊天室,而不是一个聊天室。用户可以提供一个字符串,它可以是聊天室的“名称”,这将创建一个新的聊天室。任何试图加入此聊天室的人都会彼此共享广播,但不会与其他聊天室中的人共享广播。与IRC非常相似

我的问题如下:

1:如果聊天室还不存在,如何创建具有唯一名称的聊天室? 2:我如何检查现有聊天室是否存在并获取其引用


聊天室的名称将通过URL或查询参数提供,这一部分很简单。我只是不完全确定如何唯一地识别Akka聊天室,然后按姓名检索该演员。

您可以在Akka中命名演员,而不是:

Akka.system.actorOf(Props[ChatRoom])
你应该:

Akka.system.actorOf(Props[ChatRoom],"room1")
然后,根据您使用的Akka版本,使用
Akka.system.actorFor(“room1”)
Akka.system.actorSelection(“room1”)
获取想要的聊天室的引用。

使用Akka特性。您可以使用eventBus和LookupClassification实现基于主题的发布-订阅,其中“主题”是roomID,订阅者是每个房间的参与者或每个客户端的web套接字参与者

import akka.event.EventBus
import akka.event.LookupClassification

final case class MsgEnvelope(topic: String, payload: Any)

/**
 * Publishes the payload of the MsgEnvelope when the topic of the
 * MsgEnvelope equals the String specified when subscribing.
 */
class LookupBusImpl extends EventBus with LookupClassification {
  type Event = MsgEnvelope
  type Classifier = String
  type Subscriber = ActorRef

  // is used for extracting the classifier from the incoming events  
  override protected def classify(event: Event): Classifier = event.topic

  // will be invoked for each event for all subscribers which registered themselves
  // for the event’s classifier
  override protected def publish(event: Event, subscriber: Subscriber): Unit = {
    subscriber ! event.payload
  }

  // must define a full order over the subscribers, expressed as expected from
  // `java.lang.Comparable.compare`
  override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
    a.compareTo(b)

  // determines the initial size of the index data structure
  // used internally (i.e. the expected number of different classifiers)
  override protected def mapSize: Int = 128

}
然后注册你的演员(实际上,你会记下每个房间里有多少用户,当用户进入房间时订阅,当房间里没有人时取消订阅并杀死演员)

该消息将根据roomID进行切换

lookupBus.publish(MsgEnvelope("room1", "hello room1"))
lookupBus.publish(MsgEnvelope("room2", "hello room2"))
lookupBus.publish(MsgEnvelope("room3", "hello dead letter"))

如果有两个房间,那么如何获取房间参考。在对它们进行不同命名后,您可以使用actorFor或actorSelection获取每个房间的参考,然后向其发送消息。我正在尝试使用这个Akka.system.actorOf(Props[ChatRoom],“room1”),但当我使用Akka.system.actorSelection(“room1”)时该文件室未被即将加入的成员加入。actorSelection将只返回表示给定文件室的ActorRef,然后由您向其发送加入消息。val first=Akka.system.actorSelection(“room1”)(first?join(username)).map{case Connected(枚举器)=>//创建一个Iteratee来使用提要val Iteratee=Iteratee.foreach[JsValue]{event=>first!Talk(用户名,(事件\“文本”).as[String])}.map{{{u=>first!Quit(用户名)}(Iteratee,枚举器)}我使用这个代码dut不工作。
lookupBus.publish(MsgEnvelope("room1", "hello room1"))
lookupBus.publish(MsgEnvelope("room2", "hello room2"))
lookupBus.publish(MsgEnvelope("room3", "hello dead letter"))