package org.ifsoft.websockets;
import org.jivesoftware.util.JiveGlobals;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.security.*;
import java.util.*;
import java.text.*;
import java.net.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
import org.eclipse.jetty.websocket.api.annotations.*;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
import org.jivesoftware.util.ParamUtils;
public final class XMPPServlet extends WebSocketServlet
{
private static Logger Log = LoggerFactory.getLogger( "XMPPServlet" );
public XMPPServlet()
{
}
@Override public void configure(WebSocketServletFactory factory)
{
factory.getPolicy().setMaxTextMessageSize(64000000);
factory.setCreator(new WSocketCreator());
}
public class WSocketCreator implements WebSocketCreator
{
@Override public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
Log.info("WSocketCreator ");
for (String subprotocol : req.getSubProtocols())
{
Log.info("WSocketCreator found protocol " + subprotocol);
if ("sip".equals(subprotocol) || "verto".equals(subprotocol))
{
return getSIPSocket(subprotocol, req, resp);
}
}
return getSIPSocket("sip", req, resp);
}
private SIPWebSocket getSIPSocket(String subprotocol, ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
try {
Log.info("WSocketCreator accepted protocol " + subprotocol);
HttpServletRequest request = req.getHttpServletRequest();
String url = URLDecoder.decode( ParamUtils.getParameter(request, "url"), "UTF-8");
SIPWebSocket socket = null;
SipConnection sipConnection = new SipConnection(URI.create(url), subprotocol, 10000);
if (sipConnection != null)
{
socket = new SIPWebSocket();
socket.setSipConnection(sipConnection);
resp.setAcceptedSubProtocol(subprotocol);
}
return socket;
} catch (Exception e) {
return null;
}
}
}
@WebSocket public class SIPWebSocket {
private Session wsSession;
private SipConnection sipConnection;
public void setSipConnection(SipConnection sipConnection) {
this.sipConnection = sipConnection;
sipConnection.setSocket(this);
Log.info("setSipConnection");
}
public boolean isOpen() {
return wsSession.isOpen();
}
@OnWebSocketConnect public void onConnect(Session wsSession)
{
this.wsSession = wsSession;
//sipConnection.setSecure(wsSession.isSecure());
Log.info("onConnect");
}
@OnWebSocketClose public void onClose(int statusCode, String reason)
{
try {
sipConnection.disconnect();
} catch ( Exception e ) {
Log.error( "An error occurred while attempting to remove the socket", e );
}
Log.info(" : onClose : " + statusCode + " " + reason);
}
@OnWebSocketError public void onError(Throwable error)
{
Log.error("SIPWebSocket onError", error);
}
@OnWebSocketMessage public void onTextMethod(String data)
{
if ( !"".equals( data.trim()))
{
try {
Log.info(" : onMessage : Received : \n" + data );
sipConnection.deliver(data);
} catch ( Exception e ) {
Log.error( "An error occurred while attempting to route the packet : ", e );
}
}
}
@OnWebSocketMessage public void onBinaryMethod(byte data[], int offset, int length)
{
// simple BINARY message received
}
public void deliver(String message)
{
if (wsSession != null && wsSession.isOpen() && !"".equals( message.trim() ) )
{
try {
Log.info(" : Delivered : \n" + message );
wsSession.getRemote().sendStringByFuture(message);
} catch (Exception e) {
Log.error("SIPWebSocket deliver " + e);
Log.warn("Could not deliver : \n" + message );
}
}
}
public void disconnect()
{
Log.info("disconnect : SIPWebSocket disconnect");
try {
if (wsSession != null && wsSession.isOpen())
{
wsSession.close();
}
} catch ( Exception e ) {
try {
wsSession.disconnect();
} catch ( Exception e1 ) {
}
}
}
}
}