2013-01-18 18 views
16

Uso di Scala con Akka IO c'è un modo per avere un attore rigorosamente per l'ascolto e quando viene stabilita una connessione creare un nuovo attore che sarà quindi responsabile di tale Socket (lettura, scrittura, ecc.)?Akka Socket per attore

Finora ho questo. Il problema è che l'attore Server sta ricevendo i dati. Vorrei trasferire la proprietà del socket al nuovo attore Client creato in modo che riceva tutti i messaggi relativi al socket. Qualcuno sa come farlo?

Modifica: soluzione aggiunta. Avevo solo bisogno di passare ActorRef nel parametro aleatore di accettare

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)) 
    } 

} 

Grazie!

+0

ciò che hanno provato la tua? qual è il problema esatto? –

+0

Appena calcolato val socket = server.accept() deve essere val socket = server.accept() (client) dove client è l'attore appena creato – tkblackbelt

+5

C'è un lavoro in corso su un nuovo livello IO che il team di Akka ha progettato in collaborazione con il team spray.io sarà molto più flessibile. Potresti volerlo esaminare quando uscirà. –

risposta

3

Per rendere la risposta un po 'più visibile:

Dal Akka documentation per ServerHandle:

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

socketOwner ActorRef che dovrebbe ricevere eventi associati al SocketChannel. L'ActorRef dell'attore corrente verrà utilizzato implicitamente .

Se non viene passato al parametro al curry (solo chiamando server.accept()), l'attore corrente (Server) riceverà eventi dalla SocketChannel. Tuttavia, come suggerisce la firma del metodo, è possibile passare un ActorRef al parametro al curry in modo che gli eventi che si verificano su SocketChannel vengano gestiti da questo nuovo attore.

Lasciandoci alla soluzione aggiunto dal proprietario della questione:

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) 
} 
Problemi correlati