apache mina自定义消息传输
对于Apache Mina不太熟悉的童鞋,请移步到如下百度百科连接进行学习了解:http://baike.baidu.com/view/2668084.htm
首先建立一个new project(Server端),这里使用IDE是 eclipse;
OK,首先我们这里先配置下环境:对于Mina的日志输出使用的是slf4j,对于slf4j在开发Hibernate的时候已经很熟悉了,不需要再介绍了。另外一方面就是加入mina的core核心jar包;
1. mina-core.jar 2. slf4j-api.jar 3.slf4j-simple.jar
下面我们来书写server端的main函数类:
public class gamemain {
private static final int PORT = 8888;
public static void main(String[] args) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
// code will go here next
ProtocolCodecFilter filter= new ProtocolCodecFilter(new ProtobufCodecFactory());
//ProtobufCodecFactory 是自定义的编码工厂 需要自己实现 这个才可以实现自定义消息传输
chain.addLast("objectFilter",filter);
acceptor.setHandler(new ServerHandler() );
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind( new InetSocketAddress(PORT) );
System.out.print("game server is start!\n");
Netmessage mess=new Netmessage();
mess.setCode((short)1);
EventManager.getInstance().addNetListener(mess, new LoginListener());
}
}设置一个过滤器作用是将来自客户端输入的信息转换成自定义消息object后传递给 IoHandler,因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。
ProtocolCodecFilter filter= new ProtocolCodecFilter(new ProtobufCodecFactory());
//ProtobufCodecFactory 是自定义的编码工厂 需要自己实现 这个才可以实现自定义消息传输
chain.addLast("objectFilter",filter);设置好过滤器后,接下就必须重写编码工厂。
ProtobufCodecFactory继承自ProtocolCodecFactory类
实现大致是这样的:
public class ProtobufCodecFactory implements ProtocolCodecFactory{
private static final ProtobufEncoder ENCODER_INSTANCE = new ProtobufEncoder();
private static final ProtobufDecoder DECODER_INSTANCE = new ProtobufDecoder();
public ProtobufCodecFactory() {
}
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return DECODER_INSTANCE;
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return ENCODER_INSTANCE;
}
}然后实现自己的ProtobufEncoder和ProtobufDecoder
要正常实现与c++通信,必须根据自定义数据来实现
写一个简单的实现方案:
public class ProtobufDecoder extends CumulativeProtocolDecoder {
private static final Logger log = Logger.getLogger(ProtobufDecoder.class);
protected ProtobufDecoder() {
}
/**
* 把二进制流解码为服务器使用的数据包格式
*/
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
// private short size;//包大小
// private short type;//版本号
// private short code;//包类型
// private int roleid; // 玩家ID
IoBuffer newBuf = in.slice();
//size
int size = newBuf.getShort();
System.out.printf("c size = %d\n",size);
if (size = Short.MAX_VALUE) {
// 非法的数据长度
log.debug("Message Length Invalid size = " + size + ", throw this Message.");
return true;
}
System.out.print(newBuf.getHexDump());
//000A 0001 0001 0000 0001
System.out.printf("buffer size = %d",in.remaining());
if (size > in.remaining()) {
// 数据还不够读取,等待下一次读取
System.out.printf("Data not integrity. there is a lack of " + (size - newBuf.remaining()) + " bytes.");
return true;
}
Netmessage res=new Netmessage();
short type=newBuf.getShort();
short code=newBuf.getShort();
int roleid=newBuf.getInt();
//int roleid=newBuf.getInt();
System.out.printf("type =%d code = %d roleid = %d\n",(int)type,(int)code,roleid);
res.writeDataPack((short)size, type, code, roleid);
// BODY
int bodyLen = size-10;
if (bodyLen > 0) {
byte[] bytes = new byte;
in.get(bytes, 0, bodyLen);
res.writeData(bytes,size);
}
out.write(res);
return false;
}
}大致是这样,余下的读者可以自己去实现,ps:apache mina 开发 群http://url.cn/Pc252w
本文long原创
页:
[1]