package siebog.radigost; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.event.Observes; import javax.enterprise.inject.Default; import javax.inject.Inject; import javax.websocket.CloseReason; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import siebog.agents.AID; import siebog.interaction.ACLMessage; @ServerEndpoint("/webclient") public class WebClientSocket { private static final Logger LOG = LoggerFactory.getLogger(WebClientSocket.class); // @formatter:off public static final char MSG_REGISTER = 'r', MSG_DEREGISTER = 'd', MSG_GET_STATE = 'g', MSG_STORE_STATE = 's'; //@formatter:on private static final Map<String, Session> sessions = Collections .synchronizedMap(new HashMap<String, Session>()); @Inject private Cassandra cassandra; @OnOpen public void onOpen(Session session) { LOG.debug("WebSocket Open: {}.", session.getId()); } @OnClose public void onClose(CloseReason closeReason) { LOG.debug("WebSocket Closed: {}.", closeReason.getReasonPhrase()); } @OnMessage public void onMessage(String message, Session session) { if (message == null || message.isEmpty()) throw new IllegalArgumentException("Messages cannot be empty."); char cmd = message.charAt(0); String content = message.substring(1); switch (cmd) { case MSG_REGISTER: doRegister(content, session); break; case MSG_DEREGISTER: doUnregister(content, session); break; case MSG_GET_STATE: doGetState(content, session); break; case MSG_STORE_STATE: doStoreState(content); break; } } public void sendMessageToClient(@Observes @Default ACLMessage msg) { Set<String> processed = new HashSet<>(); AID aid = msg.receivers.iterator().next(); synchronized (sessions) { Session session = sessions.get(aid.getHost()); if (session != null && processed.add(aid.getHost())) { session.getAsyncRemote().sendText(msg.toString()); } } } private void doRegister(String platformId, Session session) { sessions.put(platformId, session); } private void doUnregister(String platformId, Session session) { sessions.remove(platformId); } private void doGetState(String aid, Session session) { String state = cassandra.getState(aid); session.getAsyncRemote().sendText(state); } private void doStoreState(String content) { int delimiter = getDelimiter(content); String aid = content.substring(0, delimiter); String state = getState(content, delimiter); cassandra.setState(aid, state); } private int getDelimiter(String content) { int delimiter = content.indexOf('$'); if (delimiter <= 0) throw new IllegalArgumentException("AID cannot be empty."); return delimiter; } private String getState(String content, int delimiter) { return delimiter == content.length() - 1 ? "" : content.substring(delimiter + 1); } }