multithreading - Akka Socket por actor
sockets scala (1)
Para hacer la respuesta un poco más visible:
De la documentación de Akka para ServerHandle
:
def accept ()(implicit socketOwner: ActorRef): SocketHandle
socketOwner ActorRef que debería recibir eventos asociados con el SocketChannel. El ActorRef para el Actor actual se usará implícitamente.
Si no se pasa nada al parámetro al curry (solo se llama server.accept()
), el Actor (Servidor) actual recibirá eventos del SocketChannel. Sin embargo, como sugiere la firma del método, puede pasar un ActorRef al parámetro al curry para que los eventos que ocurren en el SocketChannel sean manejados por este nuevo Actor.
Dejándonos con la solución añadida por el propietario de la pregunta:
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)
}
Al usar Scala con Akka IO, ¿hay una manera de tener un Actor estrictamente para escuchar y luego, cuando se establece una conexión, cree un nuevo actor que será responsable de ese Socket (Lectura, Escritura, etc.)?
Hasta ahora tengo esto. El problema es que el actor del servidor está recibiendo los datos. Me gustaría transferir la propiedad del socket al nuevo actor Cliente creado para que reciba cualquier mensaje relacionado con el socket. ¿Alguien sabe cómo hacer eso?
Edición: solución añadida. Solo necesitaba pasar el ActorRef al parámetro curry de 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))
}
}
¡Gracias!