现在我正在学习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();
}
}
};
}
答案 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;发件人。