一个自己倒腾的简单的通信框架(目前只是基于请求响应模式),集成底层的API,目的在于提高通信层的开发效率。该通信框架包括如下几个功能:
1.服务端采用NIO模式,提高通信速率
2.内部提供可选连接池方式,尽可能的将连接重用,提高开发效率。
3.提供过滤器自定义
4.业务处理层自定义
5.提供负载均衡
6.连接选择器与消息选择器分离
7.客户端采用连接池模式,具有自动识别服务端是否存活的功能。
下面给出一个小的Demo,采用MINA官方的时间服务器示例来做,其主要功能是客户端向服务端发送一个简单的请求,服务端打印客户端的请求,并返回给客户端当前的请求时间。
先写服务端,业务对象的定义需要实现通信框架的FPHandler接口。FPHandler接口当中定义了如下几个方法
messRecv(FPSession session, byte[] mess) 当信道当中接收消息时触发该方法
messSend(FPSession session, byte[] mess) 当信道当中有消息发送时触发该方法
sessionClosed(FPSession session) 当信道关闭时触发
sessionCreated(FPSession session) 当新连接产生时出发该方法
自定义服务端TestHandler:
public class TestHandler implements FPHandler{
@Override
public void messRecv(FPSession session, byte[] mess) {
try {
if(mess != null){
String Message = new String(mess,"UTF-8");
// 打印客户端信息
System.out.println("Client:" + Message);
// 构造发送给客户端的时间信息
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 向客户端发送信息
session.write(("Server4328:"+sdf.format(new Date())).getBytes("UTF-8"));
}else{
session.write("b".getBytes("UTF-8"));
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
@Override
public void messSend(FPSession session, byte[] mess) {
}
@Override
public void sessionClosed(FPSession session) {
}
@Override
public void sessionCreated(FPSession session) {
session.setPool(true);
}
}
编写启动服务端的类,用于启动服务端
public static void main(String[] args) {
try {
// 使用NIO的方式开始连接
FPAcceptor accept = new FPNIOAcceptor();
// 设置业务处理对象
accept.setHandlerClass(TestHandler.class);
// 设置过滤器(可增加多条过滤器)
// accept.getFilterList().add(TestFilter.class);
// 设置负载均衡服务器地址
// accept.setLbServer(new InetSocketAddress("192.168.7.26", 4323));
// 设置服务器端监听端口
accept.setPort(4327);
// 开启服务,这里是阻塞方式。
accept.startServer();
} catch (Exception e) {
e.printStackTrace();
}
}
好了,这里服务端编写完毕,下面写客户端,客户端负责向服务端发送信息,并接收服务端返回的消息,客户端调用方式很简单;示例代码如下
FPIOConnector con = new FPIOConnector(true,new FPInetAddress("192.168.7.26",4327));
// true:表示使用连接池模式,第二个参数用于定义服务端地址与端口
byte[] rebytes = con.request(line.trim().getBytes("UTF-8"));
System.out.println(new String(rebytes,"UTF-8")+"耗时:"+(end-start)+"毫秒");
下面来写一个完整的客户端实现TestC.java,用户从键盘获取输入,并向服务端发送请求,并接收服务端的请求。
public class Test_C {
/**
* @date created on Aug 6, 2010
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while((line = br.readLine()) != null){
long start = System.currentTimeMillis();
// true:设置连接池模式
// FPInetAddress 服务器地址,端口号
FPIOConnector con = new FPIOConnector(true,new FPInetAddress("192.168.7.26",4327));
try {
// 向服务端请求
byte[] rebytes = con.request(line.trim().getBytes("UTF-8"));
long end = System.currentTimeMillis();
System.out.println(new String(rebytes,"UTF-8")+"耗时:"+(end-start)+"毫秒");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FPComException e) {
e.printStackTrace();
}
}
}
}
下面来看下运行结果吧:首先启动服务器,接着启动客户端,在客户端任意输入字符串,将返回服务端的当前时间:如下所示
>hello fpclient Server4328:2010-10-09 14:24:32耗时:3毫秒 >hahahahha Server4328:2010-10-09 14:24:44耗时:3毫秒 >你好 Server4328:2010-10-09 14:24:48耗时:1毫秒
Client:hello fpclient Client:hahahahha Client:你好