现在我对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();
}
}
};
}
1条答案
按热度按时间vu8f3i0k1#
它只返回一个对actor(
ActorRef
)* 的引用,该actor刚刚发送了您当前正在处理的消息 *。因此,这是一个演员在代码中处理消息的一种方式。
换句话说,如果参与者A向参与者B发送消息M1,则当B调用
getSender
时,它将返回对参与者A的引用。在提供代码后编辑:
以下操作将无法正常工作:
如果你自己不是actor,你不能
ask()
并期待来自actor的响应。join()
方法是静态的,完全在actor系统之外执行!它可以(也应该)在另一个类中。这就是
getSender()
在这里没有意义的原因:不存在“akka”发送者。