版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29461259/article/details/60870595
一、说明
客户端和服务器端采用Apache的mina框架实现了APP的长连接
二、JAVA服务端
- 创建一个基于TCP/IP的非阻塞的server端的Socket
- 编写过滤器(使用mina提供的文本换行符编解码器)
- 设置读取数据的缓冲区大小
- 设置读写通道10秒内无操作进入空闲状态
- 为接收器设置管理服务
- 为Socket绑定端口
2.1长连接服务器端代码
public class Demo1Server {
//日志类的实现
private static Logger logger = Logger.getLogger(Demo1Server.class+"");
//端口号,要求客户端与服务器端一致
private static int PORT = 9088;
public static void main(String[] args){
IoAcceptor acceptor = null;
try{
//创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
//设置过滤器(使用mina提供的文本换行符编解码器)(在bind前进行)
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));
//自定义的编解码器
//acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
//设置读取数据的换从区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
//读写通道10秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
//为接收器设置管理服务
acceptor.setHandler(new Demo1ServerHandler());
//绑定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服务器启动成功... 端口号未:"+PORT);
}catch(Exception e){
logger.info("服务器启动异常..."+e.getMessage().toString());
e.printStackTrace();
}
}
}
2.2管理服务代码
public class Demo1ServerHandler extends IoHandlerAdapter {
public static Logger logger = Logger.getLogger(Demo1ServerHandler.class + "");
// 从端口接受消息,会响应此方法来对消息进行处理
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
String msg = message.toString();
System.out.println(msg);
if ("exit".equals(msg)) {
// 如果客户端发来exit,则关闭该连接
session.close(true);
}
// 向客户端发送消息
Date date = new Date();
session.write(date);
logger.info("服务器接受消息成功..." + msg);
super.messageReceived(session, message);
}
// 向客服端发送消息后会调用此方法
@Override
public void messageSent(IoSession session, Object message) throws Exception {
logger.info("服务器发送消息成功...");
super.messageSent(session, message);
}
// 关闭与客户端的连接时会调用此方法
@Override
public void sessionClosed(IoSession session) throws Exception {
logger.info("服务器与客户端断开连接...");
super.sessionClosed(session);
}
// 服务器与客户端创建连接
@Override
public void sessionCreated(IoSession session) throws Exception {
logger.info("服务器与客户端创建连接...");
super.sessionCreated(session);
}
// 服务器与客户端连接打开
@Override
public void sessionOpened(IoSession session) throws Exception {
logger.info("服务器与客户端连接打开...");
super.sessionOpened(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
logger.info("服务器进入空闲状态...");
super.sessionIdle(session, status);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
logger.info("服务器发送异常...");
super.exceptionCaught(session, cause);
}
}
三、Android客户端
- 创建一个基于TCP/IP的非阻塞的clinet端的Socket
- 编写过滤器(使用mina提供的文本换行符编解码器)
- 设置连接超时
- 为接收器设置管理服务
- 连接服务器
3.1长连接客户端代码
注意:
1. Android的网络操作放在子线程
2. 清单文件需要添加访问网络的权限
public class MinaThread extends Thread {
private IoSession session = null;
@Override
public void run() {
// Create TCP/IP connector.
IoConnector connector=new NioSocketConnector();
//编写过滤器,设置编码
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(
Charset.forName("UTF-8"),
WINDOWS.getValue(),
WINDOWS.getValue()
)
)
);
//设置超时
connector.setConnectTimeoutMillis(30000);
//为连接器设置管理服务
connector.setHandler(new MinaClientHandler());
//连接服务器
connector.connect(new InetSocketAddress(ConstantUtil.IP_ADDRESS, ConstantUtil.PORT));
}
}
3.2管理服务代码
public class MinaClientHandler extends IoHandlerAdapter {
//接收到来自服务端的消息
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String msg = message.toString();
Log.d("TEST", "客户端接收到的信息为:" + msg);
super.messageReceived(session, message);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
//向服务器端发送消息
session.write("this is client");
super.sessionOpened(session);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
Log.d("TEST", "客户端发生异常");
super.exceptionCaught(session, cause);
}
}