android 心跳的分析

最近在做一个项目中用到了心跳包的机制,其实就是传统的长连接。或许有的人知道消息推送的机制,消息推送也是一种长连接 ,是将数据有服务器端推送到客户端这边从而改变传统的“拉”的请求方式。下面我来介绍一下安卓和客户端两个数据请求的方式

1、push 这个也就是有服务器推送到客户端这边 现在有第三方技术 比如极光推送。

2、pull 这种方式就是客户端向服务器发送请求数据(http请求)


接下来 我就给大家介绍Socket tcp心跳包的机制 虽然这块不是很难,找一些网上的资料不是很全面 这个模块参照一个朋友的功能模块 自己也受益匪浅,现在分享给大家。

一、首先服务器和客户端有一次“握手”

public void connect()

{
LogUtil.e(TAG, "准备链接...");
InetAddress serverAddr;
try {
socket = new Socket(Config.Host, Config.SockectPort);
_connect = true;
mReceiveThread = new ReceiveThread();
receiveStop = false;
mReceiveThread.start();
LogUtil.e(TAG, "链接成功.");

} catch (Exception e) {
LogUtil.e(TAG, "链接出错." + e.getMessage().toString());
e.printStackTrace();
}
}


二、下面就要开启一个线程 去不断读取服务器那边传过来的数据 采用Thread去实现

private class ReceiveThread extends Thread {
private byte[] buf;
private String str = null;

@Override
public void run() {
while (true) {
try {
// LogUtil.e(TAG, "监听中...:"+socket.isConnected());
if (socket!=null && socket.isConnected()) {

if (!socket.isInputShutdown()) {
BufferedReader inStream = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String content = inStream.readLine();
if (content == null)
continue;
LogUtil.e(TAG, "收到信息:" + content);
LogUtil.e(TAG, "信息长度:"+content.length());
if (!content.startsWith("CMD:"))
continue;
int spacePos = content.indexOf(" ");
if (spacePos == -1)
continue;
String cmd = content.substring(4, spacePos);
// String body = StringUtil.DecodeBase64(content
// .substring(spacePos));
String body = content.substring(spacePos).trim();
LogUtil.e(TAG, "收到信息(CMD):" + cmd);
LogUtil.e(TAG, "收到信息(BODY):" + body);

if (cmd.equals("LOGIN"))

{
// 登录
ReceiveLogin(body);
continue;
}

if (cmd.equals("KEEPLIVE")) {
if (!body.equals("1")) {
Log.e(TAG, "心跳时检测到异常,重新登录!");
socket = null;
KeepAlive();
} else {
Date now = Calendar.getInstance().getTime();
lastKeepAliveOkTime = now;
}
continue;
}
}
} else {
if(socket!=null)
LogUtil.e(TAG, "链接状态:" + socket.isConnected());
}

} catch (Exception e) {
LogUtil.e(TAG, "监听出错:" + e.toString());
e.printStackTrace();
}
}
}

三 、Socket 是否断开了 断开了 需要重新去连接

public void KeepAlive()

{
// 判断socket是否已断开,断开就重连
if (lastKeepAliveOkTime != null) {
LogUtil.e(
TAG,
"上次心跳成功时间:"
+ DateTimeUtil.dateFormat(lastKeepAliveOkTime,
"yyyy-MM-dd HH:mm:ss"));
Date now = Calendar.getInstance().getTime();
long between = (now.getTime() - lastKeepAliveOkTime.getTime());// 得到两者的毫秒数
if (between > 60 * 1000) {
LogUtil.e(TAG, "心跳异常超过1分钟,重新连接:");
lastKeepAliveOkTime = null;
socket = null;
}

} else {
lastKeepAliveOkTime = Calendar.getInstance().getTime();
}

if (!checkIsAlive()) {
LogUtil.e(TAG, "链接已断开,重新连接.");
connect();
if (loginPara != null)
Login(loginPara);
}


//此方法是检测是否连接

boolean checkIsAlive() {
if (socket == null)
return false;
try {
socket.sendUrgentData(0xFF);
} catch (IOException e) {
return false;
}
return true;

}

//然后发送数据的方法

public void sendmessage(String msg) {
if (!checkIsAlive())
return;
LogUtil.e(TAG, "准备发送消息:" + msg);
try {
if (socket != null && socket.isConnected()) {
if (!socket.isOutputShutdown()) {
PrintWriter outStream = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);

outStream.print(msg + (char) 13 + (char) 10);
outStream.flush();
}
}
LogUtil.e(TAG, "发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}


有什么问题欢迎大家一起讨论和学习 接下来自己准备研究手机流媒体这块 欢迎大家一起学习共同进步!

源码下载地址:http://download.csdn.net/detail/wangliang198901/6567561




更多相关文章

  1. Android(安卓)OpenGL ES(八)----纹理编程框架
  2. 浅析 - Android(安卓)ContentProvider用法示例
  3. Android(安卓)Native层开发Camera应用的方法
  4. Android(安卓)客户端起HttpServer NanoHttpd
  5. Android之Activity的生命周期和Activity间的跳转和数据传递
  6. android 本地数据库sqlite的封装
  7. 数据解析
  8. Android客户端向服务器端传值——登录实现(一)
  9. Android(安卓)liveData 和ViewModel 使用翻译

随机推荐

  1. javaeye中的一些好的android博客
  2. 《宅男的android开发指南》(翻译)--2
  3. Android(安卓)近百个项目的源代码,覆盖And
  4. Android选项切换条SHSegmentControl
  5. Android(安卓)support和Androidx库不能共
  6. Android(安卓)集成facebook 第三方登陆
  7. 项目中listView常用属性设置
  8. Android(安卓)Wifi:使用Android(安卓)Inst
  9. Android学习笔记(九) Android文件读写操
  10. 分享20个Android游戏源码,…