package geniusweb.partiesserver.websocket; import java.io.IOException; import java.util.List; import java.util.logging.Level; import java.util.stream.Collectors; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import geniusweb.actions.PartyId; import geniusweb.partiesserver.Constants; import geniusweb.partiesserver.repository.RunningPartiesRepo; import geniusweb.partiesserver.repository.RunningPartyInfo; import tudelft.utilities.listener.Listener; import tudelft.utilities.logging.ReportToLogger; import tudelft.utilities.logging.Reporter; /** * Returns a websocket that communicates the list of currently available * (runnable) parties. Every time something changes, a new list of parties is * sent. */ @ServerEndpoint("/running") public class RunningListSocket { private Listener changeListener; // final, but only initialized in // startSession. private Session session; private RunningPartiesRepo repo; private SendBuffer outstream; private final Reporter log; public RunningListSocket() { this(new ReportToLogger("partiesserver")); } public RunningListSocket(Reporter reporter) { this.log = reporter; } @OnOpen public void start(Session session) throws IOException { this.session = session; this.outstream = new SendBuffer(session.getBasicRemote(), log); repo = getRepo(); changeListener = new Listener() { @Override public void notifyChange(PartyId data) { sendUpdatedParties(); } }; repo.addListener(changeListener); sendUpdatedParties(); } /** * Send the currently running parties to the client. */ private void sendUpdatedParties() { List list = repo.list().stream() .map(party -> new RunningPartyInfo(party)) .collect(Collectors.toList()); log.log(Level.FINE, "sending updated running parties list " + list); try { outstream.send(Constants.getJackson().writeValueAsString(repo.list())); } catch (IOException e) { log.log(Level.SEVERE, "Internal problem converting json", e); } } @OnMessage public void onMessage(String message, Session session) { log.log(Level.WARNING, "runninglistsocket does not handle incoming messages (" + message + ")"); } @OnClose public void onClose() { try { outstream.stop(); session.close(); } catch (IOException e) { log.log(Level.SEVERE, "Failed to close websocket", e); } repo.removeListener(changeListener); } @OnError public void onError(Throwable t) throws Throwable { log.log(Level.SEVERE, "Internal problem converting json", t); } /** * FactoryMethod for testing * * @return RunningPartiesRepo */ protected RunningPartiesRepo getRepo() { return RunningPartiesRepo.instance(); } }