Hi,
I developed a xml parsing server using Mina server (1.1.7) which keep listening
at port 23000 for incoming xml message. It is working fine most of the time
except a couple of times in a day the server gets the data a byte at a time
forcing the client to timed out after 30 seconds. Normally the messages are
processed within 20-50 ms. The tcpdump tracefile shows the costant client
window size of 65535, where as our server tcp window size starts with win 5840
<mss 1460,nop,nop,sackOK> and decreases slowly. Once the client restart their
application, every thing is fine. Mina server is running on centos 5.0, with
4GB RAM connecting to the client through dedicated T1 line. Current TCP/IP
settings are follows
$cat /proc/sys/net/ipv4/tcp_window_scaling 1
$cat /proc/sys/net/ipv4/tcp_sack
1
$cat /proc/sys/net/ipv4/tcp_timestamps
1
$cat /proc/sys/net/core/rmem_default
126976
$cat /proc/sys/net/core/rmem_max
131071
$cat /proc/sys/net/core/wmem_default
126976
$cat /proc/sys/net/core/wmem_max
131071
Client is running on windows server
-Server.java
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
XmlExchangeServerIoHandler handler = new XmlExchangeServerIoHandler();
handler.setIoAcceptor(acceptor);
acceptor.bind(new InetSocketAddress(23000, handler);
Handler.java
public void sessionCreated(IoSession session) throws Exception
{
if (session.getTransportType() == TransportType.SOCKET)
((SocketSessionConfig) session.getConfig() ).setReceiveBufferSize(1024);
session.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
session.getFilterChain().addLast("protocolFilter", new ProtocolCodecFilter(new
XmlCodecFactory(false)));
session.setAttribute("XML_MESSAGE_OBJECT", new XmlMessage());
}
public void messageReceived(IoSession session, Object message) throws
Exception
{
logger.debug("{}", session);
XmlMessage xmlMessage = (XmlMessage) message;
logger.info("{}", "xmlMessage="+xmlMessage);
ArrayList<String> xmlMsgList =
appUtil.getXmlMessages(xmlMessage.getMessage());
// Process the complete messages one by one
if (xmlMsgList != null && xmlMsgList.size() > 0)
{
StringBuffer sbPartialMsgs = null;
/* Check for any completed xml messages */
for (int i = 0; i < xmlMsgList.size(); i++)
{
String xmlString = xmlMsgList.get(i);
if (appUtil.isACompleteMessage(xmlString))
{
if (isShutDownMessage(xmlString)) // authenticate shutdown
{
sbPartialMsgs = null;
if (acceptor != null && acceptor.isManaged(new
InetSocketAddress(23000)))
{
acceptor.unbindAll();
}
}
else
{
logger.info("{}", " xmlRequest->"+xmlString);
WrmsCommand command = new WrmsCommand(session);
//convert to jibx object and process the message here
AuditBean auditBean = command.execute(xmlString);
String xmlResponse = auditBean.getOneLineResXml();
// send notification emails.
session.write(new XmlMessage(xmlResponse));
// Insert an audit record in the database
}
}
else
{
if (sbPartialMsgs == null)
sbPartialMsgs = new StringBuffer();
sbPartialMsgs.append(xmlString);
}
}
// Resets the session message object
session.setAttribute("XML_MESSAGE_OBJECT", null);
session.setAttribute("XML_MESSAGE_IN_TIME", null);
if (sbPartialMsgs != null && sbPartialMsgs.length() > 0)
{
logger.debug("{}", "Setting the partial message back into session:
"+sbPartialMsgs.toString());
session.setAttribute("XML_MESSAGE_OBJECT", new
XmlMessage(sbPartialMsgs.toString()));
}
}
else
{
logger.debug("{}", session);
logger.error("xmlMsgList is NULL or has no elemenets in it...Check
your logic in decoder.doDecode()");
}
}