Теперь я немного изучаю Akka, но я не могу понять точного значения getSender()
. В this official document, метод getSender()
используется и объяснение, какЧто означает «getSender()» в Акке?
// Reply to original sender of message getSender().tell(msg + ":" + getSelf());
Это, как представляется, способ ответа, поэтому этот актер должен реагировать на актера, который отправил сообщение и этот метод является то, что делает его на самом деле. И я смущен, потому что не понимаю, дает ли 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)
, сначала актер запрашивает новое сообщение другого актера, а затем в методе onReceive(Object message)
, другой участник отвечает true
, выполняя как getSender().tell(true, ref);
. В этом обстоятельстве getSender()
дает первый актер, который спросил. Разве это не странно, потому что первый актер, который попросил, дал true
другому актеру, который должен дать true
первому актеру? Ваш ответ был бы очень полезен, но я до сих пор не ясно, извините.
EDIT: Вы сказали, что это не работает, но оно работает. Вы знакомы с 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();
}
}
};
}
Я понимаю возвращаемое значение метода 'getSender()'. Тем не менее, я до сих пор не путаюсь с некоторыми пунктами, пожалуйста, см. Мой дополнительный вопрос, если это возможно. –
Хорошо, вы сбиты с толку, потому что ваш класс смешивает две проблемы: * обработка событий в websocket * с * обработкой сообщений актера *. Кроме того, метод ask() в методе соединения не будет работать, потому что ask() не вызывается аккой akka, а статическим методом! поэтому getSender() не возвращает ссылку на актер, поскольку источник сообщения не является актером. Вы видите, что я имею в виду? –
Существует огромное количество информации, позвольте мне видеть ... Во-первых, что вы подразумеваете под обработкой событий _websocket с обработкой сообщений actor? Можете быть более конкретными? Во-вторых, я могу понять, что вы скажете, может быть, это нехорошо, не следуя теории Акки. И на самом деле, что я должен интерпретировать этот код? Есть ли у вас какие-либо идеи? –