package org.jboss.pitbull.internal.nio.websocket;
import org.jboss.pitbull.Connection;
import org.jboss.pitbull.OrderedHeaders;
import org.jboss.pitbull.RequestHeader;
import org.jboss.pitbull.ResponseHeader;
import org.jboss.pitbull.StatusCode;
import org.jboss.pitbull.internal.nio.http.HttpResponse;
import org.jboss.pitbull.internal.nio.socket.BufferedBlockingInputStream;
import org.jboss.pitbull.internal.nio.socket.EventHandler;
import org.jboss.pitbull.internal.nio.socket.ManagedChannel;
import org.jboss.pitbull.internal.nio.websocket.impl.oio.ClosingStrategy;
import org.jboss.pitbull.internal.nio.websocket.impl.oio.HttpRequestBridge;
import org.jboss.pitbull.internal.nio.websocket.impl.oio.HttpResponseBridge;
import org.jboss.pitbull.internal.nio.websocket.impl.oio.OioWebSocket;
import org.jboss.pitbull.internal.nio.websocket.impl.oio.WebSocketConnectionManager;
import org.jboss.pitbull.internal.util.OrderedHeadersImpl;
import org.jboss.pitbull.server.handlers.WebSocketHandler;
import org.jboss.pitbull.websocket.WebSocket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class WebSocketEventHandler implements EventHandler
{
protected WebSocketHandler handler;
protected WebSocket webSocket;
protected ExecutorService executorService;
protected Connection connection;
protected ManagedChannel channel;
protected BufferedBlockingInputStream inputStream;
protected WebSocketExecutor webSocketExecutor;
public WebSocketEventHandler(Connection connection, ManagedChannel channel, ExecutorService executorService, WebSocketHandler handler)
{
this.connection = connection;
this.channel = channel;
this.executorService = executorService;
this.handler = handler;
}
public void handshake(final RequestHeader requestHeader, final ByteBuffer leftOverBuffer) throws Exception
{
inputStream = new BufferedBlockingInputStream(channel, leftOverBuffer);
HttpRequestBridge requestBridge = new HttpRequestBridge()
{
@Override
public String getHeader(String name)
{
return requestHeader.getHeaders().getFirstHeader(name);
}
@Override
public String getRequestURI()
{
return requestHeader.getUri();
}
@Override
public InputStream getInputStream()
{
return inputStream;
}
@Override
public boolean isSecure()
{
return connection.isSecure();
}
};
final ResponseHeader responseHeader = new ResponseHeader()
{
OrderedHeaders headers = new OrderedHeadersImpl();
@Override
public StatusCode getStatusCode()
{
return StatusCode.SWITCHING_PROTOCOLS;
}
@Override
public OrderedHeaders getHeaders()
{
return headers;
}
};
final HandshakeOutputStream os = new HandshakeOutputStream(responseHeader, channel, 8192);
HttpResponseBridge responseBridge = new HttpResponseBridge()
{
@Override
public String getHeader(String name)
{
return responseHeader.getHeaders().getFirstHeader(name);
}
@Override
public void setHeader(String name, String val)
{
responseHeader.getHeaders().setHeader(name, val);
}
@Override
public OutputStream getOutputStream()
{
return os;
}
@Override
public void startUpgrade()
{
}
@Override
public void sendUpgrade() throws IOException
{
os.flush();
}
};
ClosingStrategy closingStrategy = new ClosingStrategy()
{
@Override
public void doClose() throws IOException
{
channel.close();
}
};
OioWebSocket oioWebSocket = WebSocketConnectionManager.establish(handler.getProtocolName(), requestBridge, responseBridge, closingStrategy);
if (oioWebSocket == null)
{
HttpResponse response = new HttpResponse(StatusCode.BAD_REQUEST);
byte[] bytes = response.responseBytes();
channel.writeBlocking(ByteBuffer.wrap(bytes));
}
webSocket = new WebSocketImpl(connection, oioWebSocket);
webSocketExecutor = new WebSocketExecutor(channel, webSocket, handler, inputStream, executorService);
}
@Override
public void handleRead(ManagedChannel channel)
{
try
{
channel.suspendReads();
executorService.execute(webSocketExecutor);
}
catch (Exception e)
{
channel.close();
}
}
@Override
public void shutdown()
{
}
}