package controllers; import akka.actor.ActorRef; import com.fasterxml.jackson.databind.JsonNode; import managers.AccountManager; import models.Account; import models.services.WebSocketService; import play.Logger; import play.db.jpa.JPA; import play.db.jpa.Transactional; import play.libs.F; import play.mvc.Http; import play.mvc.Security; import play.mvc.WebSocket; import javax.inject.Inject; @Transactional @Security.Authenticated(Secured.class) public class WebSocketController extends BaseController { /** * Handles the web socket channel by invoking Akka actor. * * @return Web socket instance including JSON nodes * @Transactional(readOnly = true) public WebSocket webSocket() { final Account account = this.getCurrentAccount(); // called when the WebSocket Handshake is done. return new WebSocket() { @Override public void onReady(In<JsonNode> in, Out<JsonNode> out) { if (account == null) { out.close(); return; } @SuppressWarnings("unused") final ActorRef actor = WebSocketService.getInstance().getActorForAccount(account, in, out); // For each event received on the socket, in.onMessage(new F.Callback<JsonNode>() { public void invoke(JsonNode wsMessage) { WebSocketService.getInstance().handleWsMessage(account, wsMessage); } }); // When the socket is closed. in.onClose(new F.Callback0() { public void invoke() { WebSocketService.getInstance().stopActor(account); //Logger.info("[WS] Disconnected User ID: " + account.id); } }); } }; return null; } /** * Returns the current account ID from current HTTP context. * * @return Account of current user * private Account getCurrentAccount() { try { return JPA.withTransaction(new F.Function0<Account>() { @Override public Account apply() throws Throwable { return accountManager.findById(Long.valueOf(Http.Context.current().session().get("id"))); } }); } catch (Throwable throwable) { Logger.error("Error while fetching account for WebSocket initialization: " + throwable.getMessage()); return null; } } */ }