improved setting of default message maximums

This commit is contained in:
Greg Wilkins 2011-09-01 10:48:43 +10:00
parent 31eb258e1f
commit 9528870b23
9 changed files with 111 additions and 87 deletions

View File

@ -112,6 +112,10 @@ public interface WebSocket
void disconnect(); void disconnect();
boolean isOpen(); boolean isOpen();
/* ------------------------------------------------------------ */
/**
* @param ms The time in ms that the connection can be idle before closing
*/
void setMaxIdleTime(int ms); void setMaxIdleTime(int ms);
/** /**
@ -124,6 +128,12 @@ public interface WebSocket
*/ */
void setMaxBinaryMessageSize(int size); void setMaxBinaryMessageSize(int size);
/* ------------------------------------------------------------ */
/**
* @return The time in ms that the connection can be idle before closing
*/
int getMaxIdleTime();
/** /**
* Size in characters of the maximum text message to be received * Size in characters of the maximum text message to be received
* @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters * @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters

View File

@ -434,6 +434,11 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
return -1; return -1;
} }
public int getMaxIdleTime()
{
return _endp.getMaxIdleTime();
}
public int getMaxBinaryMessageSize() public int getMaxBinaryMessageSize()
{ {
return -1; return -1;
@ -554,13 +559,10 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
public void setFakeFragments(boolean fake) public void setFakeFragments(boolean fake)
{ {
// TODO Auto-generated method stub
} }
public boolean isFakeFragments() public boolean isFakeFragments()
{ {
// TODO Auto-generated method stub
return false; return false;
} }
} }

View File

@ -418,6 +418,12 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
return _maxTextMessage; return _maxTextMessage;
} }
/* ------------------------------------------------------------ */
public int getMaxIdleTime()
{
return _endp.getMaxIdleTime();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public int getMaxBinaryMessageSize() public int getMaxBinaryMessageSize()
{ {

View File

@ -95,10 +95,9 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
private volatile String _closeMessage; private volatile String _closeMessage;
private volatile boolean _closedIn; private volatile boolean _closedIn;
private volatile boolean _closedOut; private volatile boolean _closedOut;
private int _maxTextMessageSize; private int _maxTextMessageSize=-1;
private int _maxBinaryMessageSize=-1; private int _maxBinaryMessageSize=-1;
static static
{ {
try try
@ -113,9 +112,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
private final WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler(); private final WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler();
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private final WebSocket.FrameConnection _connection = new WSFrameConnection(); private final WebSocket.FrameConnection _connection = new WSFrameConnection();
@ -190,9 +186,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
{} {}
}; };
} }
_maxTextMessageSize=buffers.getBufferSize();
_maxBinaryMessageSize=-1;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -410,8 +403,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
private class WSFrameConnection implements WebSocket.FrameConnection private class WSFrameConnection implements WebSocket.FrameConnection
{ {
volatile boolean _disconnecting; volatile boolean _disconnecting;
int _maxTextMessage=WebSocketConnectionD12.this._maxTextMessageSize;
int _maxBinaryMessage=WebSocketConnectionD12.this._maxBinaryMessageSize;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void sendMessage(String content) throws IOException public void sendMessage(String content) throws IOException
@ -491,25 +482,31 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setMaxTextMessageSize(int size) public void setMaxTextMessageSize(int size)
{ {
_maxTextMessage=size; _maxTextMessageSize=size;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setMaxBinaryMessageSize(int size) public void setMaxBinaryMessageSize(int size)
{ {
_maxBinaryMessage=size; _maxBinaryMessageSize=size;
}
/* ------------------------------------------------------------ */
public int getMaxIdleTime()
{
return _endp.getMaxIdleTime();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public int getMaxTextMessageSize() public int getMaxTextMessageSize()
{ {
return _maxTextMessage; return _maxTextMessageSize;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public int getMaxBinaryMessageSize() public int getMaxBinaryMessageSize()
{ {
return _maxBinaryMessage; return _maxBinaryMessageSize;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -728,7 +725,13 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
// No size limit, so handle only final frames // No size limit, so handle only final frames
if (lastFrame) if (lastFrame)
_onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8)); _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8));
else
{
LOG.warn("Frame discarded. Text aggregation disabed for {}",_endp);
_connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Text frame aggregation disabled");
}
} }
// append bytes to message buffer (if they fit)
else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize())) else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
{ {
if (lastFrame) if (lastFrame)
@ -764,6 +767,11 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
_aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize()); _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
_aggregate.put(buffer); _aggregate.put(buffer);
} }
else
{
LOG.warn("Frame discarded. Binary aggregation disabed for {}",_endp);
_connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Binary frame aggregation disabled");
}
} }
} }
} }

View File

@ -68,6 +68,8 @@ public class WebSocketFactory
private final Acceptor _acceptor; private final Acceptor _acceptor;
private WebSocketBuffers _buffers; private WebSocketBuffers _buffers;
private int _maxIdleTime = 300000; private int _maxIdleTime = 300000;
private int _maxTextMessageSize = 16*1024;
private int _maxBinaryMessageSize = -1;
public WebSocketFactory(Acceptor acceptor) public WebSocketFactory(Acceptor acceptor)
{ {
@ -130,6 +132,42 @@ public class WebSocketFactory
_buffers = new WebSocketBuffers(bufferSize); _buffers = new WebSocketBuffers(bufferSize);
} }
/**
* @return The initial maximum text message size (in characters) for a connection
*/
public int getMaxTextMessageSize()
{
return _maxTextMessageSize;
}
/**
* Set the initial maximum text message size for a connection. This can be changed by
* the application calling {@link WebSocket.Connection#setMaxTextMessageSize(int)}.
* @param maxTextMessageSize The default maximum text message size (in characters) for a connection
*/
public void setMaxTextMessageSize(int maxTextMessageSize)
{
_maxTextMessageSize = maxTextMessageSize;
}
/**
* @return The initial maximum binary message size (in bytes) for a connection
*/
public int getMaxBinaryMessageSize()
{
return _maxBinaryMessageSize;
}
/**
* Set the initial maximum binary message size for a connection. This can be changed by
* the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
* @param maxTextMessageSize The default maximum binary message size (in bytes) for a connection
*/
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
{
_maxBinaryMessageSize = maxBinaryMessageSize;
}
/** /**
* Upgrade the request/response to a WebSocket Connection. * Upgrade the request/response to a WebSocket Connection.
* <p>This method will not normally return, but will instead throw a * <p>This method will not normally return, but will instead throw a
@ -191,6 +229,10 @@ public class WebSocketFactory
throw new HttpException(400, "Unsupported draft specification: " + draft); throw new HttpException(400, "Unsupported draft specification: " + draft);
} }
// Set the defaults
connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize);
connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize);
// Let the connection finish processing the handshake // Let the connection finish processing the handshake
connection.handshake(request, response, protocol); connection.handshake(request, response, protocol);
response.flushBuffer(); response.flushBuffer();

View File

@ -24,70 +24,11 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
public abstract class WebSocketHandler extends HandlerWrapper implements WebSocketFactory.Acceptor public abstract class WebSocketHandler extends HandlerWrapper implements WebSocketFactory.Acceptor
{ {
private WebSocketFactory _webSocketFactory; private final WebSocketFactory _webSocketFactory=new WebSocketFactory(this,32*1024);
private int _bufferSize=64*1024;
private int _maxIdleTime=-1;
/* ------------------------------------------------------------ */ public WebSocketFactory getWebSocketFactory()
/** Get the bufferSize.
* @return the bufferSize
*/
public int getBufferSize()
{ {
return _bufferSize; return _webSocketFactory;
}
/* ------------------------------------------------------------ */
/** Set the bufferSize.
* @param bufferSize the bufferSize to set
*/
public void setBufferSize(int bufferSize)
{
_bufferSize = bufferSize;
}
/* ------------------------------------------------------------ */
/** Get the maxIdleTime.
* @return the maxIdleTime
*/
public int getMaxIdleTime()
{
return (int)(_webSocketFactory==null?_maxIdleTime:_webSocketFactory.getMaxIdleTime());
}
/* ------------------------------------------------------------ */
/** Set the maxIdleTime.
* @param maxIdleTime the maxIdleTime to set
*/
public void setMaxIdleTime(int maxIdleTime)
{
_maxIdleTime = maxIdleTime;
if (_webSocketFactory!=null)
_webSocketFactory.setMaxIdleTime(maxIdleTime);
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
*/
@Override
protected void doStart() throws Exception
{
_webSocketFactory=new WebSocketFactory(this,_bufferSize);
if (_maxIdleTime>=0)
_webSocketFactory.setMaxIdleTime(_maxIdleTime);
super.doStart();
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop()
*/
@Override
protected void doStop() throws Exception
{
super.doStop();
_webSocketFactory=null;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -32,7 +32,13 @@ import javax.servlet.http.HttpServletResponse;
* which is also the max frame byte size (default 8192). * which is also the max frame byte size (default 8192).
* <p> * <p>
* The initParameter "maxIdleTime" can be used to set the time in ms * The initParameter "maxIdleTime" can be used to set the time in ms
* that a websocket may be idle before closing (default 300,000). * that a websocket may be idle before closing.
* <p>
* The initParameter "maxTextMessagesSize" can be used to set the size in characters
* that a websocket may be accept before closing.
* <p>
* The initParameter "maxBinaryMessagesSize" can be used to set the size in bytes
* that a websocket may be accept before closing.
* *
*/ */
public abstract class WebSocketServlet extends HttpServlet implements WebSocketFactory.Acceptor public abstract class WebSocketServlet extends HttpServlet implements WebSocketFactory.Acceptor
@ -48,9 +54,18 @@ public abstract class WebSocketServlet extends HttpServlet implements WebSocketF
{ {
String bs=getInitParameter("bufferSize"); String bs=getInitParameter("bufferSize");
_webSocketFactory = new WebSocketFactory(this,bs==null?8192:Integer.parseInt(bs)); _webSocketFactory = new WebSocketFactory(this,bs==null?8192:Integer.parseInt(bs));
String mit=getInitParameter("maxIdleTime"); String max=getInitParameter("maxIdleTime");
if (mit!=null) if (max!=null)
_webSocketFactory.setMaxIdleTime(Integer.parseInt(mit)); _webSocketFactory.setMaxIdleTime(Integer.parseInt(max));
max=getInitParameter("maxTextMessageSize");
if (max!=null)
_webSocketFactory.setMaxTextMessageSize(Integer.parseInt(max));
max=getInitParameter("maxBinaryMessageSize");
if (max!=null)
_webSocketFactory.setMaxBinaryMessageSize(Integer.parseInt(max));
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -53,8 +53,8 @@ public class WebSocketMessageD06Test
return _serverWebSocket; return _serverWebSocket;
} }
}; };
wsHandler.setBufferSize(8192); wsHandler.getWebSocketFactory().setBufferSize(8192);
wsHandler.setMaxIdleTime(1000); wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
wsHandler.setHandler(new DefaultHandler()); wsHandler.setHandler(new DefaultHandler());
_server.setHandler(wsHandler); _server.setHandler(wsHandler);
_server.start(); _server.start();

View File

@ -64,8 +64,8 @@ public class WebSocketMessageD12Test
return __serverWebSocket; return __serverWebSocket;
} }
}; };
wsHandler.setBufferSize(8192); wsHandler.getWebSocketFactory().setBufferSize(8192);
wsHandler.setMaxIdleTime(1000); wsHandler.getWebSocketFactory().setMaxIdleTime(1000);
wsHandler.setHandler(new DefaultHandler()); wsHandler.setHandler(new DefaultHandler());
__server.setHandler(wsHandler); __server.setHandler(wsHandler);
__server.start(); __server.start();