设为首页 收藏本站
查看: 866|回复: 0

[经验分享] apache mina自定义消息传输

[复制链接]

尚未签到

发表于 2018-11-23 06:15:03 | 显示全部楼层 |阅读模式
对于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[bodyLen];
            in.get(bytes, 0, bodyLen);
            res.writeData(bytes,size);
        }
        out.write(res);
        return false;
    }
}大致是这样,余下的读者可以自己去实现,ps:apache mina 开发 群http://url.cn/Pc252w
本文long原创




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-638350-1-1.html 上篇帖子: centos5.8 x64编译安装apache httpd 2.4.9 下篇帖子: IIS APACHE NGINX相比较
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表