Conrad Congrene wrote:
Hi everyone
I'm fairly new to MINA and have created a server which will receive
text-based commands. Using the TextLineCodecFactory as the
ProtocolCodecFilter seems to do the job well.
Say that I wanted to modify the server to accept byte-based commands
aswell (or just pure byte commands and then converted to a string), what
codec/filter can I add? Do I have to create one?
I did this on a server recently. We have both text-based and
binary-based protocols running on it (on different ports). What I had
to do was write:
* a new "BinaryCodecFactory", which instantiates:
* a "BinaryProtocolDecoder" (which converts incoming bytes into a
"message" object), and
*a "BinaryProtocolEncoder" (which converts outgoing "response" objects
back into bytes
* and a "BinaryProtocolHandler" (which responds to the incoming messages
that the decoder creates.
e.g.:
public class CacheServer {
...
protocolAcceptor = new NioSocketAcceptor();
protocolAcceptor.setDefaultLocalAddress(new
InetSocketAddress(protocolPort));
DefaultIoFilterChainBuilder filterChainBuilder =
protocolAcceptor.getFilterChain();
filterChainBuilder.addLast("codec", new
ProtocolCodecFilter(BinaryCodecFactory(this, cacheNode)));
protocolAcceptor.setHandler(new BinaryProtocolHandler());
...
}
public class BinaryCodecFactory implements ProtocolCodecFactory {
public BinaryCodecFactory(CacheServerControl serverControl, CacheNode
cacheNode) {
encoder = new BinaryProtocolEncoder();
decoder = new BinaryProtocolDecoder(serverControl, cacheNode);
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return decoder;
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return encoder;
}
private ProtocolEncoder encoder;
private ProtocolDecoder decoder;
}
public class BinaryProtocolEncoder implements ProtocolEncoder {
...
}
public class BinaryProtocolDecoder extends CumulativeProtocolDecoder {
...
}
public class BinaryProtocolHandler extends IoHandlerAdapter {
...
}
Trickiest part about this setup was writing the BinaryProtocolDecoder.
Bytes get delivered in chunks, so you are not guaranteed that a call to
decode will pass you all of the bytes needed to decode a message. So
you need to a) account for this situation and not throw an error, and b)
make sure you save the bytes that make up the first part of a message so
that you will be able to decode the full message once the second part
gets delivered. Use CumulativeProtocolDecoder here - it helps simplify
this process a lot.
HTH,
DR