Hibernate系列学习阶段到此结束了,那么紧接着进入Apache Mina的开发学习,很多童鞋在微薄和QQ中疑问Himi为什么突然脱离游戏开发了,嘿嘿,其实可能更多的童鞋已经看出来了,Himi在偏向服务器Server端开发了,Hibernate、MySQL等都是为了Server端Mina开发而做的铺垫,当前的Apache Mina才是Himi真正的目的。哈哈。Himi的技术目标是“一个人能做出一个网游~”,OK.不多说其他的了,开始Himi的Apache mina开发之旅吧。

对于Apache Mina不太连接的童鞋,请移步到如下百度百科连接进行学习了解:

http://baike.baidu.com/view/2668084.htm

首先建立一个new project(Server端),这里Himi使用IDE是 eclipse;

OK,首先我们这里先配置下环境:对于Mina的日志输出使用的是slf4j,对于slf4j在开发Hibernate的时候已经很熟悉了,不需要再介绍了。另外一方面就是加入mina的core核心jar包;

1. mina-core.jar         2. slf4j-api.jar         3.slf4j-simple.jar

然后我们首先创建两个类:

HimiObject.java

/*** @author Himi*/import java.io.Serializable;public class HimiObject implements Serializable{public HimiObject(int id,String name){this.id=id;this.name=name;}private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

这个类是个消息Object,它用于server与client端的交互的数据,它需要序列化,所以我们使用Serializable接口;至于在mina框架中起到什么作用这个后续来说;

ClientMinaServerHanlder.java

/*** @author Himi*/import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;public class ClientMinaServerHanlder extends IoHandlerAdapter {private int count = 0;// 当一个新客户端连接后触发此方法.public void sessionCreated(IoSession session) {System.out.println("新客户端连接");}// 当一个客端端连结进入时 @Overridepublic void sessionOpened(IoSession session) throws Exception {count++;System.out.println("第 " + count + " 个 client 登陆!address: : "+ session.getRemoteAddress());}// 当客户端发送的消息到达时:@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {// // 我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为String:// String s = (String) message;// // Write the received data back to remote peer// System.out.println("收到客户机发来的消息: " + s);// // 测试将消息回送给客户端 session.write(s+count); count++;HimiObject ho = (HimiObject) message;System.out.println(ho.getName());ho.setName("serverHimi");session.write(ho);}// 当信息已经传送给客户端后触发此方法.@Overridepublic void messageSent(IoSession session, Object message) {System.out.println("信息已经传送给客户端");}// 当一个客户端关闭时@Overridepublic void sessionClosed(IoSession session) {System.out.println("one Clinet Disconnect !");}// 当连接空闲时触发此方法.@Overridepublic void sessionIdle(IoSession session, IdleStatus status) {System.out.println("连接空闲");}// 当接口中其他方法抛出异常未被捕获时触发此方法@Overridepublic void exceptionCaught(IoSession session, Throwable cause) {System.out.println("其他方法抛出异常");}}

本类主要是继承IoHandlerAdapter并且重写其类的一些函数,至于每个函数的作用Himi都已经在代码中加以注视;本类的作用:

此类是用以处理消息的也可说是个消息处理器,当客户端有消息传给server端的时候,或者server端传递给Client端的时候(Client端也会有个消息处理器)都会通过消息处理器进行处理。

OK,下面我们来书写server端的main函数类:

/*** @author Himi*/import java.io.IOException;
import java.net.InetSocketAddress;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class MinaServer {/*** @param args*/public static void main(String[] args) {//创建一个非阻塞的server端Socket ,用NIOSocketAcceptor acceptor = new NioSocketAcceptor();/*---------接收字符串---------*/
//      //创建一个接收数据过滤器
//      DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
//      //设定过滤器一行行(/r/n)的读取数据
//      chain.addLast("mychin", new ProtocolCodecFilter(new TextLineCodecFactory()   ));/*---------接收对象---------*///创建接收数据的过滤器DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();//设定这个过滤器将以对象为单位读取数据ProtocolCodecFilter filter= new ProtocolCodecFilter(new ObjectSerializationCodecFactory());chain.addLast("objectFilter",filter);//设定服务器消息处理器acceptor.setHandler(new ClientMinaServerHanlder());//服务器绑定的端口int bindPort = 9988;//绑定端口,启动服务器try {acceptor.bind(new InetSocketAddress(bindPort));} catch (IOException e) {System.out.println("Mina Server start for error!"+bindPort);e.printStackTrace();}System.out.println("Mina Server run done! on port:"+bindPort);}
}

IoService 是负责底层通讯接入,而 IoHandler 是负责业务处理的。那么 MINA 架构图中的 IoFilter 作何用途呢?答案是你想作何用途都可以。但是有一个用途却是必须的,那就是作为 IoService 和 IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceived,这个方法的第二个参数是一个 Object 型的消息,总所周知,Object 是所有 Java 对象的基础,那到底谁来决定这个消息到底是什么类型呢?这个取决于我们后面设定的过滤器!

对于在mina中建立一个server,步骤如下:

1. 建立一个SockerAcceptor ,除了启动server之外它还可以为我们可以生成过滤器DefaultIoFilterChainBuilder、设置消息处理器等功能;

2.设置过滤器

3. 设置消息处理器

其实很容易不是么? 哈哈;

OK,这里多说一些:

对于消息处理器 DefaultIoFilterChainBuilder,它的作用是用于设定收发的形式,例如:

   //创建一个接收数据过滤器DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();//设定过滤器一行行(/r/n)的读取数据chain.addLast("mychin", new ProtocolCodecFilter(new TextLineCodecFactory()   ));

这样设置一个过滤器作用是将来自客户端输入的信息转换成一行行的文本后传递给 IoHandler,因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。

ps.而如果我们不提供任何过滤器的话,那么在 messageReceived 方法中的第二个参数类型就是一个 byte 的缓冲区,对应的类是 org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放在 IoHandler 中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得 IoHandler 不只是业务处理,还得充当协议解析的任务。

mina自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilter(SSL加密)等。

当我们设置如下:

//创建接收数据的过滤器DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();//设定这个过滤器将以对象为单位读取数据ProtocolCodecFilter filter= new ProtocolCodecFilter(new ObjectSerializationCodecFactory());chain.addLast("objectFilter",filter);

这样以来我们server可以收发Object对象啦;

acceptor.setHandler(new ClientMinaServerHanlder());

这里是设置消息处理器,绑定在我们的ClientMinaServerHanlder类上,其实mina对于收发处理已经完全交给开发者来进行处理,所以至于在消息处理器如何编写和处理就放任不会管了;

OK,现在我们可以run一下启动server端了;

当然我们现在也可以来测试了,当前我们还没有书写Client端的代码,所以我们使用terminal终端进行测试,OK,打开你的terminal

然后输入  telnet localhost 9988

观察服务器打印:

OK,没有任何问题;但是这时候大家不要在终端书写内容给server,因为我们server的消息处理器中的接受Client的函数中做了如下处理:

// 当客户端发送的消息到达时:@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {// // 我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为String:// String s = (String) message;// // Write the received data back to remote peer// System.out.println("收到客户机发来的消息: " + s);// // 测试将消息回送给客户端 session.write(s+count); count++;HimiObject ho = (HimiObject) message;System.out.println(ho.getName());ho.setName("serverHimi");session.write(ho);}

Himi这里server处理client端发来的数据处理函数(如上代码)中,当Client发送数据过来的时候,将消息message强制转换成了一个HimiObject对象,然后改个name重写发给Client端,但是由于Client端是使用终端模拟登陆根本无法接受这个对象,所以会出异常;

但是到这里大家应该懂得,HimiObject类的作用了;哈哈

下面我们来书写Client客户端,对于建立一个Client端,其实步骤雷同,步骤如下:

1 . 建立一个NioSocketConnector对象;

2. 设定过滤器

3. 设定消息处理器

代码如下:

/*** @author Himi*/
import java.net.InetSocketAddress;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;public class MainClient {public static void main(String[] args) {// 创建一个tcp/ip 连接NioSocketConnector connector = new NioSocketConnector();/*---------接收字符串---------*/// //创建接收数据的过滤器// DefaultIoFilterChainBuilder chain = connector.getFilterChain();// // 设定这个过滤器将一行一行(/r/n)的读取数据// chain.addLast("myChin", new ProtocolCodecFilter(// new TextLineCodecFactory()));/*---------接收对象---------*/// 创建接收数据的过滤器DefaultIoFilterChainBuilder chain = connector.getFilterChain();// 设定这个过滤器将以对象为单位读取数据ProtocolCodecFilter filter = new ProtocolCodecFilter(new ObjectSerializationCodecFactory());// 设定服务器端的消息处理器:一个SamplMinaServerHandler对象,chain.addLast("objectFilter",filter);// 设定服务器端的消息处理器:一个 SamplMinaServerHandler 对象,connector.setHandler(new ClientMinaServerHanlder());// Set connect timeout.connector.setConnectTimeoutCheckInterval(30);// 连结到服务器:ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",9988));// Wait for the connection attempt to be finished.cf.awaitUninterruptibly();cf.getSession().getCloseFuture().awaitUninterruptibly();connector.dispose();}
}

不多说了,很eazy:那么我们继续看Clent端的消息处理器以及HimiObject:

ClentMinaServerHanlder:

/*** @author Himi*/import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;public class ClientMinaServerHanlder extends IoHandlerAdapter {// 当一个客端端连结到服务器后@Overridepublic void sessionOpened(IoSession session) throws Exception {
//      session.write("我来啦........");HimiObject ho = new HimiObject(1,"Himi");session.write(ho);}// 当一个客户端关闭时@Overridepublic void sessionClosed(IoSession session) {System.out.println("I'm Client &&  I closed!");}// 当服务器端发送的消息到达时:@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {
//      // 我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为 String:
//      String s = (String) message;
//      // Write the received data back to remote peer
//      System.out.println("服务器发来的收到消息: " + s);
//      // 测试将消息回送给客户端 session.write(s);HimiObject ho = (HimiObject) message;System.out.println(ho.getName());}
}

Client的HimiObject与服务器Server的HimiObejct类一模一样!

可能有童鞋不理解为什么server端与client的HimiObject一模一样,这里Himi说下,通过Client端的消息处理器可以看出,当我们Client端连接到服务器后,首先会写给Server端一个HimiObject对象!那么服务器之前说过了,接受到Client端的消息后首先将消息强制转换成HimiObject对象然后处理;

既然Client端发的是Object,那么当然我们的服务器也要有对应的此Object对象才可以,否则如何获取这个Object?  大家应该很容易理解;

OK,不多说直接运行Client端,观察结果:

OK,结果正常。

Client与Server消息逻辑如下:

1. Client->传递HimiObject给Server

2. Server端接受message强制转换HimiObject,并且设置其name为serverHimi,然后再传递给Client

3. 客户端接受message强制转换HimiObject,然后获取此类的name打印出来!

Mina框架并实现Server与Client端的简单消息传递!相关推荐

  1. 搭建Apache Mina框架并实现Server与Client端的简单消息传递

    http://www.himigame.com/apache-mina/831.html :(作者新浪微博: @李华明Himi ) 转载自[黑米GameDev街区] 原文链接: http://www. ...

  2. 【Apache Mina2.0开发之一】搭建Apache Mina框架并实现Server与Client端的简单消息传递!

    Hibernate系列学习阶段到此结束了,那么紧接着进入Apache Mina的开发学习,很多童鞋在微薄和QQ中疑问Himi为什么突然脱离游戏开发了,嘿嘿,其实可能更多的童鞋已经看出来了,Himi在偏 ...

  3. 【Apache Mina2.0开发之一】搭建Apache Mina框架并实现Server与Client端消息传递

    Hibernate系列学习阶段到此结束了,那么紧接着进入Apache Mina的开发学习,很多童鞋在微薄和QQ中疑问Himi为什么突然脱离游戏开发了,嘿嘿,其实可能更多的童鞋已经看出来了,Himi在偏 ...

  4. mysql数据实时同步:Canal安装部署、kafka安装、zk安装、mysql安装、Canal Server+Canal Client HA,Canal+mysql+Kafka,相关验证(学习笔记)

    目录 Canal安装部署 1.1. 服务器准备 1.2. 设置主机名并配置hosts 1.3. 免密设置 1.4. 设置ntp时间 1.5. 关闭防火墙 1.6. 关闭selinux 1.7. 安装J ...

  5. Client端异步Callback的应用与介绍

    转载:http://blog.csdn.net/goalbell/archive/2007/09/16/1787213.aspx 1.Client端异步Callback的介绍:它是通过前端Client ...

  6. 【Apache Mina2.0开发之二】自定义实现Server/Client端的编解码工厂(自定义编码与解码器)!...

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/apache-mina/831.html ☞ ...

  7. 轻量级Rpc框架设计--motan源码解析六:client端服务发现

    一, Client端初始化工作 client端通过RefererConfigBean类实现InitializingBean接口的afterPropertiesSet方法, 进行下面三项检查配置工作: ...

  8. Oracle监听器Server端与Client端配置实例

    Listener.ora.tnsnames.ora这两个文件常常因为格式问题而不好用,我平时都是配置好了留个备份,以后都是拷贝过去改改就好了!嘿嘿~~~ 因为平时使用linux的时候较多,所以有时还会 ...

  9. BluetoothLE-Multi-Library 一个能够连接多台蓝牙设备的库,它可以作为client端,也可以为server端。支持主机/从机,外围设备连接。...

    github地址:https://github.com/qindachang/BluetoothLE-Multi-Library BluetoothLE-Multi-Library 一个能够连接多台蓝 ...

最新文章

  1. MMDetection V2.0:更快更强的通用目标检测平台
  2. ios 常用数学函数
  3. [Python设计模式] 第1章 计算器——简单工厂模式
  4. linux-centos7 常用的基本命令--用户账号管理、查看和修改主机名
  5. 关于PCB板设计中电阻电容等封装的选择
  6. ☆☆☆Windows服务器部署及原理☆☆☆
  7. Nitrux安装JDK-10(Linux通用)教程
  8. passing '' as 'this' argument discards qualifiers [-fpermissive]
  9. 三星s8 android9.0官方rom,三星S8+港版安卓9官方固件rom刷机包:TGY-G9550ZHU3DSD3
  10. 速查!你名下绑定了几个微信
  11. 尊享e生爸妈版2020:60岁以上的老人也能买百万医疗险了?!
  12. 钛媒体2022 EDGE AWARDS全球创新评选之「年度最佳企业服务品牌」揭榜
  13. 构建AWS Site-to-Site IPsec实现内网互联
  14. java背单词_java实现背单词程序
  15. xmanager5链接linux配置,xmanager连接linux5的方法
  16. 嵌入式 Linux 编程
  17. Vue-Video-player多rtmp视频流显示在同一个页面+流媒体服务器部署
  18. DSP28335 SPI的使用
  19. 中国垃圾分类产业链现状动态及未来发展前景预测报告(2022-2027年)
  20. opnet之aloha进阶csma

热门文章

  1. 项目经理面对项目陷困境该这样采取措施
  2. 阿里云 OSS 之图片处理
  3. 电脑键盘的快捷功能,你学会了工作效率提高一半以上
  4. 1:什么是空指针?区分 NULL、0 和 ‘\0‘
  5. RCTF 2018线上赛 writeup
  6. matplotlib从折线图入门并解决中文乱码
  7. 羽毛球业余分级新标准
  8. 南京邮电大学c语言实验报告3v2,南京邮电大学操作系统实验报告
  9. Unity URP Shader Graph Unit 阴影 light Atten
  10. 递归算法中的小Tips