package com.ponysdk.core.servlet;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ponysdk.core.Application;
import com.ponysdk.core.UIContext;
import com.ponysdk.core.socket.ConnectionListener;
import com.ponysdk.ui.server.basic.PPusher;
import com.ponysdk.ui.terminal.Dictionnary;
import com.ponysdk.ui.terminal.Dictionnary.APPLICATION;
public class WebSocketServlet extends org.eclipse.jetty.websocket.WebSocketServlet {
protected static final Logger log = LoggerFactory.getLogger(WebSocketServlet.class);
private static final long serialVersionUID = 1L;
public int maxIdleTime = -1;
@Override
public WebSocket doWebSocketConnect(final HttpServletRequest req, final String arg1) {
final long key = Long.parseLong(req.getParameter(APPLICATION.VIEW_ID));
final Application applicationSession = (Application) req.getSession().getAttribute(Application.class.getCanonicalName());
if (applicationSession == null) throw new RuntimeException("Invalid session, please reload your application");
JettyWebSocket jettyWebSocket;
final UIContext uiContext = applicationSession.getUIContext(key);
uiContext.acquire();
try {
UIContext.setCurrent(uiContext);
jettyWebSocket = newJettyWebsocket();
PPusher.get().initialize(jettyWebSocket);
} finally {
UIContext.remove();
uiContext.release();
}
return jettyWebSocket;
}
protected JettyWebSocket newJettyWebsocket() {
return new JettyWebSocket(maxIdleTime);
}
public static class JettyWebSocket implements OnTextMessage, com.ponysdk.core.socket.WebSocket {
protected Connection connection;
protected ConnectionListener connectionListener;
protected UIContext uiContext;
private final int maxIdleTime;
public JettyWebSocket(final int maxIdleTime) {
this.maxIdleTime = maxIdleTime;
this.uiContext = UIContext.get();
}
@Override
public void onOpen(final Connection connection) {
log.info("Connection received from: " + connection.toString());
this.connection = connection;
this.connection.setMaxIdleTime(maxIdleTime);
this.connectionListener.onOpen();
}
@Override
public void send(final String msg) throws IOException {
connection.sendMessage(msg);
}
@Override
public void addConnectionListener(final ConnectionListener connectionListener) {
this.connectionListener = connectionListener;
}
@Override
public void onClose(final int closeCode, final String message) {
log.info("Connection lost from: " + connection.toString() + ". Code: " + closeCode + ". Message: " + message);
connectionListener.onClose();
uiContext.destroy();
}
@Override
public void onMessage(final String message) {
try {
uiContext.notifyMessageReceived();
final JSONObject jso = new JSONObject();
jso.put(Dictionnary.APPLICATION.PING, (int) (System.currentTimeMillis() * .001));
connection.sendMessage(jso.toString());
} catch (final JSONException e) {
log.error("", e);
} catch (final IOException e) {
log.error("", e);
}
}
@Override
public void close() {
if (connection != null) connection.close();
}
}
public void setMaxIdleTime(final int maxIdleTime) {
this.maxIdleTime = maxIdleTime;
}
}