package vlove.web.websocket;
import java.util.UUID;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.websocket.WebSocket;
import org.atmosphere.websocket.WebSocketEventListenerAdapter;
import org.atmosphere.websocket.WebSocketHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Configurable;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
@Configurable
public class VloveWebSocketHandler extends WebSocketHandler {
protected static final Logger log = LoggerFactory.getLogger(VloveWebSocketHandler.class);
private final ITopic<String> messageQueue;
private static final String uuid = UUID.randomUUID().toString();
private AtmosphereResource r;
public VloveWebSocketHandler() {
messageQueue = Hazelcast.getDefaultInstance().getTopic("websocket-messaging");
messageQueue.addMessageListener(new MessageListener<String>() {
@Override
public void onMessage(Message<String> message) {
log.debug("Sending message.");
VloveWebSocketHandler.this.broadcast(message.getMessageObject());
}
});
}
@Override
public void onTextMessage(WebSocket webSocket, String message) {
log.debug("Received a message from an agent: {}", message);
if (message.contains("\"messageType\":\"vlove.model.json.AgentConnectionMessage\"")) {
// Agent just connected
broadcast("Send your connection info, please.");
}
}
@Override
public void onOpen(WebSocket webSocket) {
log.debug("WebSocket agent connection established.");
// Accept the handshake by suspending the response.
r = webSocket.resource();
// Create a Broadcaster based on the path
Broadcaster b = lookupBroadcaster(r.getRequest().getPathInfo());
r.setBroadcaster(b);
r.addEventListener(new WebSocketEventListenerAdapter());
r.suspend(-1);
// broadcast()
}
public void broadcast(String message) {
if (r != null) {
log.debug("Sending message to agent.");
r.getBroadcaster().broadcast(message);
} else {
log.warn("{} not connected, could not broadcast message.", uuid);
}
}
/**
* Retrieve the {@link Broadcaster} based on the request's path info.
*
* @param pathInfo
* @return the {@link Broadcaster} based on the request's path info.
*/
private Broadcaster lookupBroadcaster(String pathInfo) {
String[] decodedPath = pathInfo.split("/");
Broadcaster b = BroadcasterFactory.getDefault().lookup(decodedPath[decodedPath.length - 1], true);
return b;
}
}