Android 基于mina框架实现和后台长连接
主要引入org.apache.mina
主要应用的场景,后台与服务器可以实时通信,实时交互,传输少量及时数据,多数场景传递预订好的指令
服务器需要提供ip和端口号,绑定socket
this.connector = new NioSocketConnector();
// 设置日志记录器
this.connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addFirst("reconnection", new IoFilterAdapter());
// 设置编解码过滤器
this.connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CodecFactory(Charset.forName("UTF-8"))));
// 指定业务逻辑处理器
this.connector.setHandler(sessionHandler = new SessionHandler(context, this));
// 设置链接超时时间
this.connector.setConnectTimeoutMillis(8000);
MIna框架初始化完毕。
绑定IP和端口
address = new InetSocketAddress(host, port);
ConnectFuture future = this.connector.connect(address);
future.awaitUninterruptibly(); // 等待是否连接成功,相当于转异步执行为同步
try {
session = future.getSession();
} catch (Exception e) {
e.printStackTrace();
Intent intent = new Intent(SocketClient.ACTION_SOCKET_CONNECT_FAILED);
context.sendBroadcast(intent);
return null;
}
发送连接通知
socketClient.sendMessage(SocketMessageTypes.REQUEST_CONNECT_SERVER, data); //data为与服务器端交互的数据
接收服务器端通知
class SessionHandler extends IoHandlerAdapter{
public void messageReceived(IoSession session, Object message) throws Exception {
SocketMessage msg = (SocketMessage) message;
type = msg.getType();
Object data = msg.getData();
switch (type) {
}
}
}
完成与服务器端数据交互
心跳检测连接是否出问题
/**
* 会话关闭
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
Log.e(Utility.LOG_TAG, "sessionClosed................会话异常关闭");
Intent intent = new Intent(SocketClient.ACTION_SOCKET_COLSE);
context.sendBroadcast(intent);
socketClient.reConn();
}
/**
* 发生异常
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
Log.e(Utility.LOG_TAG, "exceptionCaught:会话发生异常" + cause.getMessage());
Intent intent = new Intent(SocketClient.ACTION_SOCKET_EXCEPTION);
context.sendBroadcast(intent);
cause.printStackTrace();
session.close(true);
}
public void reConn() {
while (isNeadToReConn) {
try {
Thread.sleep(3000);
ConnectFuture future = connector.connect(address);
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
if (session != null) {
JSONObject data = new JSONObject();
TeacherBean teacher = TeacherBean.getInstance();
data.put("teaId", teacher.teaId);
data.put("classId", teacher.classId);
Log.e(Utility.LOG_TAG, "重连服务器。。。。。。");
session.write(new SocketMessage(SocketMessageTypes.REQUEST_CONNECT_SERVER, data));
}
break;
} catch (Exception ex) {
Log.e(Utility.LOG_TAG, "重连服务器失败,3秒再连接一次:" + ex.getMessage() + " address:" + address.getHostName() + ":" + address.getPort());
}
}
}
主体流程如此,已经在项目中使用,连接稳定。