2016-06-12 11 views
1
class HomeController @Inject (implicit actorSystem:ActorSystem, materializer :Materializer) extends Controller 
{ 

    case class sendMsg(msg:JsValue) 
    class MYWSACTOR(out:ActorRef,mainActor:ActorRef) extends Actor 
    { 

     def receive = 
     { 

      case msg : JsValue => 
      mainActor ! sendMsg(msg) 

      case sendMsg(msg) => 
      { 
       /* validation part */ 
       out ! msg 
      } 
     } 

    } 

} 

val mainActor = actorSystem.actorOf(Props[MYWSACTOR],"mainActor") 

def object MYWSACTOR 
{ 
    def props(out:ActorRef) = Props(new MYWSACTOR(out,mainActor)) 
} 

def socket = WebSocket.accept[JsValue,JsValue] 
{ 
    request => 

    ActorFlow.actorRef(out => MYWSACTOR.props(out)) 

} 

Ich bin neu in Akka und Scala. Ich versuche eine Chat-Anwendung mit Akka in Scala und Play Framework 2.5.3 zu erstellen. Ich habe den obigen Code aus der offiziellen Dokumentation verwendet. Ich wollte nur einen anderen Akteur (mainActor im obigen Code) erstellen, so dass die Nachricht vom Client zuerst validiert und dann zurückgeschickt wird. Aber das Problem ist MainActor ist nicht in der Lage, die msg an eine andere Klasse case sendMsg zu senden. wenn ich auch versuchen, den Schauspieler zu jedem anderen Punkt zu erstellen, gibt es mir Kompilierungsfehler Unerwartete Ausnahme: Vorläufige Ausnahmekann keinen anderen Akteur in Akka WebSocket erstellen

+0

Lesen Sie Ihren Code sorgfältig, 'MYWSACTOR' nimmt zwei Argumente, daher' val mainActor = actorSystem.actorOf (Props [MYWSACTOR], "mainActor") 'ist nicht gültig, Sie müssen zusätzliches Argument übergeben. – liosedhel

+0

Ich bin hier verwirrt ... seit ich gerade Schauspieler mit Requisiten der MYWSACTOR-Klasse, wo ich Argumente hier übergeben muss? Es wird hilfreich sein, wenn Sie mir als Beispiel zeigen. –

+0

Lesen Sie die Dokumentation: http://doc.akka.io/docs/akka/snapshot/scala/actors.html#Props Ihr Hauptdarsteller benötigt zwei Params. Aber ich frage mich, wer wird sein Hauptdarsteller sein, sollte es null sein? (Definitiv nicht). Vielleicht brauchst du 2 verschiedene Klassen für diese Schauspieler. –

Antwort

0

Hier hoffentlich ist das, was Sie wahrscheinlich wollte:

case class SendMsg(msg: JsValue) 
case class ReceivedMessage(wsActor: ActorRef, msg: JsValue) 

class MyWsActor(out: ActorRef, mainActor:ActorRef) extends Actor { 

    def receive = { 
    case msg : JsValue => 
     mainActor ! ReceivedMessage(self, msg) 

    case SendMsg(msg) => 
     out ! msg 
    } 
} 

object MyWsActor { 
    def props(out: ActorRef, mainActor: ActorRef) = Props(new MyWsActor(out, mainActor)) 
    //or if you want to instantiate your Props with reflection 
    def props2(out: ActorRef, mainActor: ActorRef) = Props(classOf[MyWsActor], out, mainActor) 
} 

class MainActor() extends Actor { 
    def receive = { 
    case ReceivedMessage(wsActor, msg) => { 
     /* 
     Do sth with msg 
     */ 
     val result = msg 
     wsActor ! SendMsg(result) //here sender is your MyWsActor 
    } 
    } 
} 

class HomeController @Inject() (
    actorSystem: ActorSystem, 
    materializer: Materializer 
) extends Controller { 

    val mainActor = actorSystem.actorOf(Props[MainActor], "mainActor") 

    def socket = WebSocket.accept[JsValue,JsValue] { 
     request => 
     ActorFlow.actorRef(out => MyWsActor.props(out, mainActor)) 
    } 

} 

Der Schlüssel, dass Sie ist kann senden, mit der tatsächlichen Nachricht, auch ActorRef (oder standardmäßig können Sie einen Absender ActorRef aufrufen sender()) und dann können Sie diese ActorRef wiederholen.