getSender()在Akka中是什么意思?

rjjhvcjd  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(142)

现在我对Akka有了一些了解,但是我不能理解getSender()的确切含义。在this official document,中使用了getSender()方法,解释如下
// Reply to original sender of message getSender().tell(msg + ":" + getSelf());
这似乎是一个响应方法,所以这个actor必须响应发送消息的actor,而这个方法实际上是做它的。我很困惑,因为我不明白getSender()是提供接收方actor还是发送方actor。所以,你能给予我解释一下吗?

  • 谢谢-谢谢
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)方法时,首先参与者向另一个参与者询问新消息,然后在onReceive(Object message)方法中,另一个参与者通过类似于getSender().tell(true, ref);的执行以true进行应答。在这种情况下,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();
            }
        }
    };
}
vu8f3i0k

vu8f3i0k1#

它只返回一个对actor(ActorRef)* 的引用,该actor刚刚发送了您当前正在处理的消息 *。
因此,这是一个演员在代码中处理消息的一种方式。
换句话说,如果参与者A向参与者B发送消息M1,则当B调用getSender时,它将返回对参与者A的引用。

在提供代码后编辑:

以下操作将无法正常工作:

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

如果你自己不是actor,你不能ask()并期待来自actor的响应。join()方法是静态的,完全在actor系统之外执行!它可以(也应该)在另一个类中。
这就是getSender()在这里没有意义的原因:不存在“akka”发送者。

相关问题