@Override
public Action handle(AtmosphereRequest request, final AtmosphereResponse response, SocketIOSession session) throws IOException {
logger.trace("Session id[" + session.getSessionId() + "] method=" + request.getMethod() + " response HashCode=" + response.hashCode());
AtmosphereResourceImpl resource = (AtmosphereResourceImpl) request.getAttribute(ApplicationConfig.ATMOSPHERE_RESOURCE);
if ("GET".equals(request.getMethod())) {
synchronized (this) {
if (!is_open) {
response.sendError(AtmosphereResponse.SC_NOT_FOUND);
} else {
if (!isStreamingConnection) {
if (resource != null) {
resource.getRequest().setAttribute(SocketIOAtmosphereHandler.SOCKETIO_SESSION_ID, session.getSessionId());
resource.getRequest().setAttribute(SocketIOAtmosphereHandler.SOCKETIO_SESSION_OUTBOUND, session.getTransportHandler());
session.setAtmosphereResourceImpl(resource);
resource.addEventListener(new AtmosphereResourceEventListenerAdapter() {
@Override
public void onResume(AtmosphereResourceEvent event) {
if (event.isResumedOnTimeout()) {
event.getResource().write(new SocketIOPacketImpl(PacketType.NOOP).toString());
}
}
});
session.clearTimeoutTimer();
request.setAttribute(SESSION_KEY, session);
boolean resume = false;
StringBuilder data = new StringBuilder();
// if there is a Broadcaster cache, retrieve the messages from the cache, and send them
if (DefaultBroadcaster.class.isAssignableFrom(resource.getBroadcaster().getClass())) {
List<Object> cachedMessages = resource.getBroadcaster().getBroadcasterConfig().getBroadcasterCache()
.retrieveFromCache(resource.getBroadcaster().getID(), resource.uuid());
if (cachedMessages != null && !cachedMessages.isEmpty()) {
if (cachedMessages.size() > 1) {
for (Object object : cachedMessages) {
String msg = object.toString();
data.append(SocketIOPacketImpl.SOCKETIO_MSG_DELIMITER)
.append(msg.length())
.append(SocketIOPacketImpl.SOCKETIO_MSG_DELIMITER).append(msg);
}
} else if (cachedMessages.size() == 1) {
data.append(cachedMessages.get(0));
}
// something to send ?
if (!data.toString().isEmpty()) {
startSend(response);
writeData(response, data.toString());
finishSend(response);
// force a resume, because we sent data
resource.resume();
resume = true;
}
}
}
if (!resume) {
resource.disableSuspend(false);
resource.suspend(session.getRequestSuspendTime());
resource.disableSuspend(true);
}
}
} else {
// won't happend, by should be for xhr-streaming transport
response.sendError(AtmosphereResponse.SC_NOT_FOUND);
}
}
}
} else if ("POST".equals(request.getMethod())) {
if (is_open) {
int size = request.getContentLength();
if (size == 0) {
response.sendError(AtmosphereResponse.SC_BAD_REQUEST);
} else {
String data = (String) request.getAttribute(POST_MESSAGE_RECEIVED);
if (data == null) {
data = decodePostData(request.getContentType(), extractString(request.getReader()));
}
if (data == null || data.length() == 0) {
data = SocketIOSessionManagerImpl.mapper.readValue(request.getParameter("d"), String.class);
}
if (data != null && data.length() > 0) {
List<SocketIOPacketImpl> list = SocketIOPacketImpl.parse(data);
synchronized (session) {
for (SocketIOPacketImpl msg : list) {
if (msg.getFrameType().equals(SocketIOPacketImpl.PacketType.EVENT)) {
// send message on the suspended request
session.onMessage(session.getAtmosphereResourceImpl(), session.getTransportHandler(), msg.getData());
// send completion flag on the post request
writeData(response, SocketIOPacketImpl.POST_RESPONSE);
} else {
// send completion flag on the post request
writeData(response, SocketIOPacketImpl.POST_RESPONSE);
}
}
}
}
}
// force a resume on a POST request
resource.resume();
}
} else {
response.sendError(AtmosphereResponse.SC_BAD_REQUEST);
}
return Action.CANCELLED;