2017-01-21 3 views
2

Maintenant j'apprends un peu Akka, mais je ne peux pas comprendre la signification exacte de getSender(). En this official document, la méthode getSender() est utilisée et l'explication est commeQue signifie 'getSender()' dans Akka?

// Reply to original sender of message getSender().tell(msg + ":" + getSelf());

Cela semble être une méthode de réponse, de sorte que cet acteur doit répondre à un acteur qui a envoyé un message et cette méthode est ce qui le fait réellement. Et je suis confus parce que je ne comprends pas si getSender() offre l'acteur récepteur ou l'acteur expéditeur. Alors, pourriez-vous me donner une explication à ce sujet?

Merci.

public class WebSocketActor extends UntypedActor { 

/** 
* Actor's reference 
*/ 
private final static ActorRef ref = Akka.system().actorOf(new Props(WebSocketActor.class)); 

/** 
* the list of those who should get messages 
*/ 
Map<String, WebSocket.Out<JsonNode>> members = new HashMap<String, WebSocket.Out<JsonNode>>(); 

/** 
* a method adding a certain user 
* @param username a user name 
* @param in receive of WebSokcet 
* @param out sending of WebSocket 
* @throws Exception 
*/ 
public static void join(final String username, WebSocket.In<JsonNode> in, WebSocket.Out<JsonNode> out) throws Exception { 

    // causing JOIN event 
    Boolean result = (Boolean) Await.result(ask(ref, new Message(username, "", "", WebSocketEvent.JOIN, out), 1000), Duration.create(1, SECONDS)); 

    if(result) { 
     // if a message is sent,MESSAGE event will occur. 
     in.onMessage(new Callback<JsonNode>() { 
      public void invoke(JsonNode event) { 
       ref.tell(new Message(username, event.get("x").asText(), event.get("y").asText(), WebSocketEvent.MESSAGE, null), ref); 
      } 
     }); 
     // a close method when WebSocket is closed 
     in.onClose(new Callback0() { 
      public void invoke() { 
       ref.tell(new Message(username, "", "", WebSocketEvent.QUIT, null), ref); 
      } 
     }); 
    } else { 
     // sending an error 
     ObjectNode error = Json.newObject(); 
     error.put("error", result); 
     out.write(error); 
    } 
} 

/** 
* the executable method when an event happens 
* @param message an event object 
* @throws Exception 
*/ 
@Override 
public void onReceive(Object message) throws Exception { 

    // diciding whether the object is an event or not 
    Option<Message> event = EventUtil.getEvent(message); 
    if(event.isDefined()){ 
     Message m = event.get(); 
     switch (m.getEventType()) { 
      // adding to members 
      case JOIN: 
       members.put(m.getUsername(), m.getChannel()); 
       getSender().tell(true, ref); 
       break; 
      // sending all 
      case MESSAGE: 
       WebSocketMessenger.notifyAll(m.getUsername(), m.getX(), m.getY(), members); 
       break; 
      // excluding someone from members 
      case QUIT: 
       members.remove(m.getUsername()); 
       break; 
      default: 
       unhandled(message); 
       break; 
     } 
    } 

} 

}

Dans le code ci-dessus, onReceive(Object message) méthode, vous pouvez voir la méthode getSender(). Cependant, lorsque la méthode join(final String username, WebSocket.In<JsonNode> in, WebSocket.Out out) est appelée, l'acteur demande d'abord un nouveau message d'un autre acteur, puis dans la méthode onReceive(Object message), un autre acteur répond par true en exécutant getSender().tell(true, ref);. Dans cette circonstance, getSender() donne le premier acteur qui a demandé. N'est-il pas étrange parce que le premier acteur qui a demandé true à l'autre acteur qui devrait donner true au premier acteur? Votre réponse serait très utile, mais je ne suis toujours pas clair, désolé.

EDIT: Vous avez dit que cela ne fonctionne pas bien, mais cela fonctionne. Connaissez-vous PlayFramework? Si c'est le cas, il est totalement simple de saisir une image entière. Ce code est le code du contrôleur qui appelle la méthode join().

public static WebSocket<JsonNode> ws() { 
    final String username = session("username"); 
    return new WebSocket<JsonNode>() { 
     @Override 
     public void onReady(final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out) { 
      try { 
       WebSocketActor.join(username, in, out); 
      } catch (Exception e) { 
       Logger.error("Can't connect WebSocket"); 
       e.printStackTrace(); 
      } 
     } 
    }; 
} 

Répondre

2

Il retourne simplement une référence sur l'acteur (ActorRef) qui vient d'envoyer le message que vous gérez actuellement.

Ainsi, c'est un moyen pour un acteur de de répondre un message ... dans le code qui le gère.

En d'autres termes, si l'acteur A envoyer un message M1 à un B acteur, quand B appelle getSender, il renvoie une référence sur l'acteur A.

modifier après le code fourni:

Le suivant ne fonctionne pas correctement:

Boolean result = (Boolean) Await.result(ask(ref, new Message(username, "", "", WebSocketEvent.JOIN, out), 1000), Duration.create(1, SECONDS)); 

vous ne pouvez pas demander() et attendre une réponse d'un acteur, si vous n'êtes pas acteur vous. La méthode join() est statique et complètement exécutée en dehors du système d'acteur! il pourrait (et devrait) être dans une autre classe.

C'est pourquoi getSender() n'a pas de sens ici: il n'y a pas d'expéditeur "akka".

+0

Je comprends la valeur de retour de la méthode 'getSender()'. Cependant, je ne suis toujours pas confus avec certains points, s'il vous plaît voir ma question supplémentaire si possible. –

+0

D'accord, vous êtes confus car votre classe mélange deux problèmes: * la gestion des événements websocket * avec * le traitement des messages d'acteur *. De plus, ask() dans la méthode join ne fonctionnera pas - car ask() n'est pas appelé par un acteur akka, mais par une méthode statique! par conséquent, getSender() ne retournera pas une référence d'acteur, puisque l'origine du message n'est pas un acteur. Est-ce que tu vois ce que je veux dire? –

+0

Il y a une grande quantité d'informations, laissez-moi voir ... D'abord, que voulez-vous dire par _websocket gestion des événements avec le traitement des messages de l'acteur? Peux-tu être plus précis? Deuxièmement, je peux comprendre ce que vous dites peut-être, à savoir que ce n'est pas bon, ne pas suivre la théorie d'Akka. Et en fait, que dois-je interpréter ce code? Avez-vous une idée? –