如何在Akka远程演员之间发送消息?

时间:2011-10-21 02:21:17

标签: scala networking messaging actor akka

我想构建一个非常简单的聊天应用程序,该应用程序可以在没有使用Akka远程actor的中央服务器的情况下工作。

我基本上想用IP地址A启动一个应用程序实例。 然后我想用IP地址A 启动应用程序实例,告诉它远程实例位于IP地址B.

我怎么设置那个? Akka文档通常只涵盖客户端/服务器用例,甚至基本的东西让我完全糊涂了,e。 G。在哪里使用Actor.actorOfActor.register对比Actor.remote

我的代码目前看起来像这样:

import collection.mutable.{ArrayBuffer, HashSet}
import akka.actor.Actor

sealed trait Event    
/** Join tells the peer that there is a new peer and 
  * requests a list of known peers and messages. */
case class Join(user: String, ipAddress: String) extends Event
/** Join tells the peer that there is a new peer. */
case class Register(user: String, ipAddress: String) extends Event
case class Leave(user: String, ipAddress: String) extends Event    
case object GetChatLog extends Event
case object GetPeers extends Event
case class ChatLog(log: Seq[Message]) extends Event
case class Peers(peers: Seq[Peer]) extends Event
case class Message(sender: String, time: Long, message: String) extends Event

class ChatPeer(val name: String, ipAddress: String) extends Actor {
  val chat = Actor.remote.actorFor("chat:service", ipAddress, 2552) //This is not what I want...
  val messages = ArrayBuffer[Message]()
  val peers = HashSet[Peer]()

  def join = {
    (chat ? Join(name, ipAddress)).as[(Seq[Peer], Seq[Message])]
  }

  def register = chat ! Register(name, ipAddress)

  def leave = chat ! Leave(name, ipAddress)

  def send(message: String) = {
    val msg = Message(name, System.currentTimeMillis(), message)
    messages += msg
    chat ! msg
  }

  def getMessages = (chat ? GetChatLog).as[ChatLog]
    .getOrElse(throw new Exception("Couldn't get the chat log from ChatServer"))

  def getPeers = (chat ? GetPeers).as[Peers]
    .getOrElse(throw new Exception("Couldn't get the peers from ChatServer"))


  def receive = {
    case msg@Message(from, time, message) =>
      println(msg)
      messages += msg

    case GetChatLog =>
      self reply messages

    case GetPeers =>
      self reply peers

    case Join =>
      peers += Peer(name, ipAddress)
      self reply ((peers, messages))

    case Register(user, ipAddress) =>
      peers += Peer(user, ipAddress)

    case Leave(user, ipAddress) =>
      peers -= Peer(user, ipAddress)

  }
}

case class Peer(name: String, ipAddress: String)

1 个答案:

答案 0 :(得分:3)

我不确定我是否从您的示例代码中了解了您的需求。

我认为,如果你想创建一个没有专用服务器的版本,那么基本上两个对等体都必须启动并注册远程服务器

remote.start("localhost", somePort).register("chat-main", actorOf[ChatMain])

然后尝试连接到其他对等方的服务器

val otherActor = remote.actorFor("chat-main", otherHost, somePeer)

基本上,您必须同时建立对等服务器客户端。设置的其余部分是一些协商和聊天逻辑,但从技术上讲,它并不比Akka网站上的简单示例复杂得多。