package controllers.websockets; import java.util.HashMap; import java.util.Map; import models.User; import play.Logger; import play.libs.F.EventStream; /** * * @author Alex Jarvis axj7@aber.ac.uk */ public class LocationStreamManager { private static LocationStreamManager INSTANCE = null; // TODO: persist archived streams private Map<Long, LocationEventStream<LocationEvent>> archivedStreams = new HashMap<Long, LocationEventStream<LocationEvent>>(); private Map<Long, EventStream<LocationEvent>> connectedStreams = new HashMap<Long, EventStream<LocationEvent>>(); /** * Singleton * @return */ public static LocationStreamManager getInstance() { if (INSTANCE == null) { INSTANCE = new LocationStreamManager(); } return INSTANCE; } /** * Returns the location stream for a user and creates it if it does not already exist. * * @param id * @return */ public EventStream<LocationEvent> getLocationStreamForUserWithId(Long id) { EventStream<LocationEvent> locationStream = null; if (connectedStreams.containsKey(id)) { connectedStreams.remove(id); } if (archivedStreams.containsKey(id)) { locationStream = archivedStreams.get(id).eventStream(); } else { LocationEventStream<LocationEvent> archivedStream = new LocationEventStream<LocationEvent>(100); archivedStreams.put(id, archivedStream); locationStream = archivedStream.eventStream(); } if (locationStream != null) { connectedStreams.put(id, locationStream); return locationStream; } return null; } /** * Publishes a location event to a specific users location stream. * * @param user * @param locationEvent */ public void publishLocationEventToUserWithId(Long id, LocationEvent locationEvent) { LocationEventStream<LocationEvent> archiveStreamForUser = null; if (!archivedStreams.containsKey(id)) { archiveStreamForUser = new LocationEventStream<LocationEvent>(100); archivedStreams.put(id, archiveStreamForUser); } archiveStreamForUser = archivedStreams.get(id); archiveStreamForUser.publish(locationEvent); } /** * Closes the stream with the specified user id. * @param id */ public void closeStreamForUserWithId(Long id) { if (connectedStreams.containsKey(id)) { Logger.info("Removing connected stream with user id: " + id); EventStream<LocationEvent> connectedStream = connectedStreams.get(id); connectedStreams.remove(id); archivedStreams.get(id).removePipedStream(connectedStream); } } }