' getSender()在Akka中意味着什么?

时间:2017-01-21 09:18:06

标签: java akka actor

现在我正在学习Akka,但我无法理解getSender()的确切含义。 在this official document,中,使用方法getSender(),解释类似于

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

这似乎是一种响应方法,所以这个actor必须响应发送消息的actor,而这个方法实际上是什么。我感到困惑,因为我不明白getSender()是否提供接收者演员或发送者演员。那么,你能给我一个解释吗?

感谢。

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

}

}

在上面的代码中,您可以在onReceive(Object message)方法中看到getSender()方法。但是,当调用join(final String username, WebSocket.In<JsonNode> in, WebSocket.Out out)方法时,首先actor会询问另一个actor的新消息,然后在onReceive(Object message)方法中,另一个actor通过执行true来回答getSender().tell(true, ref);。 }。在这种情况下,getSender()给出了第一位提出要求的演员。这不是很奇怪,因为第一个问过的演员给了true给另一个应该给第一个演员true的演员吗? 你的答案非常有用,但我仍然不清楚,抱歉。

编辑: 你说这不好用,但它有效。 你熟悉PlayFramework吗?如果是这样的话,掌握整个画面是完全直截了当的。此代码是控制器的代码,它调用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();
            }
        }
    };
}

1 个答案:

答案 0 :(得分:3)

它只返回一个关于actor(ActorRef的引用,该引用刚刚发送了您当前正在处理的消息

因此,这是演员在处理它的代码中回答消息的方式。

换句话说,如果演员A向演员B发送消息M1,当B调用getSender时,它将返回演员A的参考。

在提供的代码后进行编辑:

以下内容无法正常运作:

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

你不能问()并期待演员的回应,如果你自己不是演员。 join()方法是静态的,完全在actor系统之外执行!它可以(而且应该)在另一个班级。

这就是为什么getSender()在这里没有意义:没有&#34; akka&#34;发件人。