简体   繁体   English

Akka Socket每个演员

[英]Akka Socket per actor

Using Scala with Akka IO is there a way to have an Actor strictly for listening and then when a connection is established create a new actor that will then be responsible for that Socket (Reading, Writing, etc)? 使用Scala和Akka IO有一种方法可以让一个Actor严格用于监听,然后在建立连接时创建一个新的actor,然后负责该Socket(阅读,写作等)?

So far I have this. 到目前为止,我有这个。 The problem is that the Server actor is receiving the data. 问题是Server actor正在接收数据。 I would like to transfer ownership of the socket to the new created Client actor so that it receives any messages related to the socket. 我想将套接字的所有权转移到新创建的Client actor,以便它接收与套接字相关的任何消息。 Anyone know how to do that? 谁知道怎么做?

Edit: added solution. 编辑:添加解决方案。 I just needed to pass the ActorRef into the curried parameter of accept 我只需要将ActorRef传递给accept的curried参数

import akka.actor._
import akka.actor.IO.SocketHandle
import java.net.InetSocketAddress


/**
 * Purpose:
 * User: chuck
 * Date: 17/01/13
 * Time: 5:37 PM
 */
object Main {

  class Server extends Actor {

    override def preStart() {
      IOManager(context.system) listen new InetSocketAddress(3333)
    }

    def receive = {

      case IO.NewClient(server) =>

        val client = context.actorOf(Props(new Client()))
        server.accept()(client)
        println("Client accepted")

      case IO.Read(socket, bytes) =>
        println("Server " + bytes)


    }
  }

  class Client() extends Actor {

    def receive = {

      case IO.Read(socket, bytes) =>
        println("Client " + bytes)

      case IO.Closed(socket, reason) =>
        println("Socket closed " + reason)

    }

  }

  def main(args: Array[String]) {
    val system = ActorSystem()
    system.actorOf(Props(new Server))
  }

}

Thanks! 谢谢!

To make the answer a little more visible : 为了使答案更加明显:

From the Akka documentation for ServerHandle : ServerHandleAkka文档中:

def accept ()(implicit socketOwner: ActorRef): SocketHandle

socketOwner ActorRef that should receive events associated with the SocketChannel. socketOwner应该接收与SocketChannel关联的事件的ActorRef。 The ActorRef for the current Actor will be used implicitly. 将隐式使用当前Actor的ActorRef。

If nothing is passed to the curried parameter (only calling server.accept() ), the current Actor (Server) will receive events from the SocketChannel. 如果没有将任何内容传递给curried参数(仅调用server.accept() ),则当前的Actor(Server)将从SocketChannel接收事件。 However as the method signature suggests, you can pass an ActorRef to the curried parameter so that events occurring on the SocketChannel will be handled by this new Actor. 但是,正如方法签名所示,您可以将ActorRef传递给curried参数,以便SocketChannel上发生的事件将由此新Actor处理。

Leaving us to the solution added by the owner of the question : 让我们接受问题所有者添加的解决方案:

def receive = {
  case IO.NewClient(server) =>
      val client = context.actorOf(Props(new Client()))
      server.accept()(client) // Transferring ownership of the socket to a new Actor
      println("Client accepted")

  case IO.Read(socket, bytes) =>
      println("Server " + bytes)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM