经过之前两篇文章,
Apache mina 入门(一)— 基础知识
Apache Mina 入门 (二)—— 异步通信机制
我们对mina 有一个基本的了解:mina是个异步通信框架,对于服务端开发,长连接、异步通信使用mina非常便捷。但也有需求,可能需要使用短连接,即每次连接都需要以下四个步骤:连接-发送-接收-断开。
使用短连接的mina 客户端不再需要IOHandler的messageReceived方法去处理业务数据,而是变换成在在短连接中,接受消息后进行业务数据处理。如何做到呢?我们只需要设置mina的UseReadOperation属性为true。
服务端代码不需改动。看Apache Mina 入门 (二)—— 异步通信机制这篇文章即可。
同步客户端代码
/**
* mina 客户端同步通讯
* 原理:mina异步通讯是建立有效的长连接,客户端通讯在长连接中进行,
* 对于mina客户端同步操作来说,长连接变换为短连接,即客户端的每次操作都需要建立连接,发送消息,接收消息,断开连接
* @author liuc
* @date 2017-12-20
*
*/
public class ClientTest {
public static void main(String[] args) throws MinaConnectTimeoutException, MinaReadTimeoutException {
//连接对象
NioSocketConnector connector = new NioSocketConnector();
//设置连接超时时间
connector.setConnectTimeoutMillis(30000L);
//添加过滤器
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new com.onion.mina.client.ByteArrayCodecFactory()));
SocketSessionConfig cfg = connector.getSessionConfig();
//实现同步的mina客户端必须设置UseReadOperation属性为true
cfg.setUseReadOperation(true);
IoSession session = null;
connector.setDefaultRemoteAddress(new InetSocketAddress("127.0.0.1", 8888));// 设置默认访问地址
//加入重连机制,重连5次,如果重连不上,则抛出异常
for (int num = 0;num < 5; num++) {
try {
ConnectFuture future = connector.connect();
future.awaitUninterruptibly(); // 等待连接创建成功
session = future.getSession(); // 获取会话
if (session.isConnected()) {
System.out.println("连接服务端"
+ "127.0.0.1"
+ ":"
+ 8888
+ "[成功]"
+ ",,时间:"
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date()));
break;
}
} catch (RuntimeIoException e) {
System.out.println(
"连接服务端"
+ "127.0.0.1"
+ ":"
+ 8888
+ "失败"
+ ",,时间:"
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date())
+ ", 连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动,异常内容:"
+ e.getMessage());
try {
Thread.sleep(1000);// 连接失败后,重连间隔5s
} catch (InterruptedException e1) {
e1.printStackTrace();
}
throw new MinaConnectTimeoutException("连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动");
}
}
if(!session.isConnected()){
System.out.println(
"连接服务端"
+ "127.0.0.1"
+ ":"
+ 8888
+ "失败"
+ ",,时间:"
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date())
+ ", 连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动,");
// 读超时
throw new MinaConnectTimeoutException("连接SOCKET服务异常,请检查SOCKET端口、IP是否正确,MSG服务是否启动");
}
// 现在已实现了连接,接下来就是发送-接收-断开了
try {
BaseMessageForServer message = new BaseMessageForServer();
String content = "hello world!";
CRC32 crc = new CRC32();
try {
crc.update(content.getBytes("GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
message.setFuncid(5);
message.setPacketIdCode(10000);
message.setContent(content);
message.setCheckCode(crc.getValue());
message.setLength(content.getBytes().length);
// 发送
session.write(message).awaitUninterruptibly();
doRead(session);
} finally {
// 断开
session.close(true);
session.getService().dispose();
connector.dispose();
}
}
public static void doRead(IoSession session) throws MinaReadTimeoutException {
// 接收
ReadFuture readFuture = session.read();
if (readFuture.awaitUninterruptibly(10000,
TimeUnit.SECONDS)) {
// System.out.println("客户端收到消息:" + message);
Object obj = readFuture.getMessage();
if(obj instanceof BaseMessageForClient){
BaseMessageForClient client = (BaseMessageForClient) obj;
System.out.println("客户端收到消息:" + client.toString());
if (client.getFuncid() == 4) {
//收到心跳包
System.out.println("收到心跳包");
session.write("1111");
}
}
} else {
// 读超时
throw new MinaReadTimeoutException("从socket中读取数据超时,请检查MSG服务端是否正常");
}
}
}
使用该客户端即可进行测试。代码源码下载地址:http://download.csdn.net/download/u012151597/10166224