Акка Сокет для актера
Используя Scala с Akka IO, есть способ, чтобы Актер строго слушал, а затем, когда установлено соединение, создайте нового актера, который будет отвечать за этот Socket (Чтение, Написание и т.д.)?
Пока у меня это есть. Проблема в том, что серверный сервер получает данные. Я хотел бы передать право собственности на сокет новому созданному клиенту, чтобы он получал любые сообщения, связанные с сокетом. Кто-нибудь знает, как это сделать?
Изменить: добавлено решение. Мне просто нужно было передать ActorRef в валютный параметр accept
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))
}
}
Спасибо!
Ответы
Ответ 1
Чтобы сделать ответ немного более заметным:
Из документации Akka для ServerHandle
:
def accept ()(implicit socketOwner: ActorRef): SocketHandle
socketOwner ActorRef, который должен получать события, связанные с SocketChannel. Будет использован ActorRef для текущего Актера неявно.
Если ничто не передается параметру curried (только вызов server.accept()
), текущий Актер (Сервер) будет получать события из SocketChannel. Однако, как указывает сигнатура метода, вы можете передать ActorRef параметру curries, чтобы события, происходящие на SocketChannel, обрабатывались этим новым Актером.
Оставив нас к решению, добавленному владельцем вопроса:
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)
}