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

Reply via email to