android socket tcp 为什么要发送心跳包
后台开启一个线程一直运行,每隔1分钟左右发送一个心跳报文给服务器,以确保时刻跟服务器链接。若超过3次服务器未对客户端发送的心跳报文做出回应则重新链接。 如果这么作的话,必须确保和服务器达成一定的应用层协议。
成都创新互联服务项目包括姚安网站建设、姚安网站制作、姚安网页制作以及姚安网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,姚安网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到姚安省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
请问如何在android下计算出心跳包的发送频率?
[图文]2013年2月2日 - //向服务器发送心跳包 sendHeartbeatPackage(...点击复制链接 与好友分享!回本站首页 分享到:...Java程序移植到android上问题解决小结Android入门第...
android 心跳包服务器怎么写
[java]
public class HeartbeatService extends Service implements Runnable
{
private Thread mThread;
public int count = 0;
private boolean isTip = true;
private static String mRestMsg;
private static String KEY_REST_MSG = "KEY_REST_MSG";
@Override
public void run()
{
while (true)
{
try
{
if (count 1)
{
Log.i("@qi", "offline");
count = 1;
if (isTip)
{
//判断应用是否在运行
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ListRunningTaskInfo list = am.getRunningTasks(3);
for (RunningTaskInfo info : list)
{
if (info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知应用,显示提示“连接不到服务器”
Intent intent = new Intent("org.yhn.demo");
intent.putExtra("msg", true);
sendBroadcast(intent);
break;
}
}
isTip = false;
}
}
if (mRestMsg != "" mRestMsg != null)
{
//向服务器发送心跳包
sendHeartbeatPackage(mRestMsg);
count += 1;
}
Thread.sleep(1000 * 3);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
private void sendHeartbeatPackage(String msg)
{
HttpGet httpGet = new HttpGet(msg);
DefaultHttpClient httpClient = new DefaultHttpClient();
// 发送请求
HttpResponse httpResponse = null;
try
{
httpResponse = httpClient.execute(httpGet);
}
catch (Exception e)
{
e.printStackTrace();
}
if (httpResponse == null)
{
return;
}
// 处理返回结果
final int responseCode = httpResponse.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK)
{
//只要服务器有回应就OK
count = 0;
isTip = true;
}
else
{
Log.i("@qi", "responseCode " + responseCode);
}
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
super.onCreate();
}
@Override
public void onDestroy()
{
super.onDestroy();
}
public void onStart(Intent intent, int startId)
{
Log.i("@qi", "service onStart");
//从本地读取服务器的URL,如果没有就用传进来的URL
mRestMsg = getRestMsg();
if (mRestMsg == null || mRestMsg == "")
{
mRestMsg = intent.getExtras().getString("url");
}
setRestMsg(mRestMsg);
mThread = new Thread(this);
mThread.start();
count = 0;
super.onStart(intent, startId);
}
public String getRestMsg()
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
Log.i("@qi", "getRestMsg() " + prefer.getString(KEY_REST_MSG, ""));
return prefer.getString(KEY_REST_MSG, "");
}
public void setRestMsg(String restMsg)
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefer.edit();
editor.putString(KEY_REST_MSG, restMsg);
editor.commit();
}
}
public class HeartbeatService extends Service implements Runnable
{
private Thread mThread;
public int count = 0;
private boolean isTip = true;
private static String mRestMsg;
private static String KEY_REST_MSG = "KEY_REST_MSG";
@Override
public void run()
{
while (true)
{
try
{
if (count 1)
{
Log.i("@qi", "offline");
count = 1;
if (isTip)
{
//判断应用是否在运行
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ListRunningTaskInfo list = am.getRunningTasks(3);
for (RunningTaskInfo info : list)
{
if (info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知应用,显示提示“连接不到服务器”
Intent intent = new Intent("org.yhn.demo");
intent.putExtra("msg", true);
sendBroadcast(intent);
break;
}
}
isTip = false;
}
}
if (mRestMsg != "" mRestMsg != null)
{
//向服务器发送心跳包
sendHeartbeatPackage(mRestMsg);
count += 1;
}
Thread.sleep(1000 * 3);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
private void sendHeartbeatPackage(String msg)
{
HttpGet httpGet = new HttpGet(msg);
DefaultHttpClient httpClient = new DefaultHttpClient();
// 发送请求
HttpResponse httpResponse = null;
try
{
httpResponse = httpClient.execute(httpGet);
}
catch (Exception e)
{
e.printStackTrace();
}
if (httpResponse == null)
{
return;
}
// 处理返回结果
final int responseCode = httpResponse.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK)
{
//只要服务器有回应就OK
count = 0;
isTip = true;
}
else
{
Log.i("@qi", "responseCode " + responseCode);
}
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
super.onCreate();
}
@Override
public void onDestroy()
{
super.onDestroy();
}
public void onStart(Intent intent, int startId)
{
Log.i("@qi", "service onStart");
//从本地读取服务器的URL,如果没有就用传进来的URL
mRestMsg = getRestMsg();
if (mRestMsg == null || mRestMsg == "")
{
mRestMsg = intent.getExtras().getString("url");
}
setRestMsg(mRestMsg);
mThread = new Thread(this);
mThread.start();
count = 0;
super.onStart(intent, startId);
}
public String getRestMsg()
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
Log.i("@qi", "getRestMsg() " + prefer.getString(KEY_REST_MSG, ""));
return prefer.getString(KEY_REST_MSG, "");
}
public void setRestMsg(String restMsg)
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefer.edit();
editor.putString(KEY_REST_MSG, restMsg);
editor.commit();
}
}
启动Service:
[java]
Intent serviceIntent = new Intent("HeartbeatService");
serviceIntent.putExtra("url",url);
startService(serviceIntent);
Intent serviceIntent = new Intent("HeartbeatService");
serviceIntent.putExtra("url",url);
startService(serviceIntent);
最后别忘了注册Server和GET_TASKS
[html]
service
android:name=".demo.HeartbeatService"
android:label="QServer"
android:persistent="true"
intent-filter
action android:name="HeartbeatService" /
/intent-filter
/service
service
android:name=".demo.HeartbeatService"
android:label="QServer"
android:persistent="true"
intent-filter
action android:name="HeartbeatService" /
/intent-filter
/service[html] view plaincopyprint?
uses-permission android:name="android.permission.GET_TASKS" /
uses-permission android:name="android.permission.GET_TASKS" /
android6.0 微信心跳包多久一次
在支持GCM的设备上,主要靠GCM来激活WhatsApp,WhatsApp启动后,会建立一个与服务器的长连接,直接通过此长连接发送Push消息,这个长连接10分钟无消息就会主动断掉,且这十分钟内不做心跳,断掉后WhatsApp客户端和它的服务器不再有连接。当有消息时候,服务器发现没有长连接会发送GCM消息,手机收到GCM消息后,会重新建立长连接来收取消息,10分钟无消息会再断开,如此循环。
IM即时通讯开发如何实现Android版智能心跳机制
IM即时通讯开发如何实现Android版智能心跳机制。
大体思路
a)延迟心跳测试法:这是测试结果准确的前提保障,我们认为长连接建立后连续三次成功的短心跳就可以很大程度的保证下一次心跳环境是正常的。
b)成功一次认定,失败连续累积认定:成功是绝对的,连续失败多次才可能是失败。
c)临界值避免:我们使用比计算出的心跳稍微小一点的值做为稳定心跳避免临界值。
d)动态调整:即使在一次完整的智能心跳计算过程中,我们没有找到最好的值,我们还有机会来进行校正。
方案需考虑到影响连接寿命的思素
在Android下,不管是GCM,还是微信,都是通过TCP长连接来进行消息收发的,TCP长连接存活,消息收发就及时,所以要对影响TCP连接寿命的因素进行研究。
1、NAT超时
大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断(NAT超时的更多描述见附录9.1)。NAT超时是影响TCP连接寿命的一个重要因素(尤其是国内),所以客户端自动测算NAT超时时间,来动态调整心跳间隔,是一个重要的优化点。
2、DHCP的租期 (lease time)
目前测试发现安卓系统对DHCP的处理有Bug,DHCP租期到了不会主动续约并且会继续使用过期IP,这个问题会造成TCP长连接偶然的断连。(租期问题的具体描述见附录9.2)。
3、网络状态变化
手机网络和WIFI网络切换、网络断开和连上等情况有网络状态的变化,也会使长连接变为无效连接,需要监听响应的网络状态变化事件,重新建立Push长连接。
心跳范围选择
1、前后台区分处理:
为了保证微信收消息及时性的体验,当微信处于前台活跃状态时,使用固定心跳。微信进入后台(或者前台关屏)时,先用几次最小心跳维持长链接。然后进入后台自适应心跳计算。这样做的目的是尽量选择用户不活跃的时间段,来减少心跳计算可能产生的消息不及时收取影响。
2、后台自适应心跳选择区间:
可根据自身产品的特点选择合适的心跳范围。
自适应心跳算法量化描述
因为每个网络的NAT时间可能不一致。所以需要区分计算,数据网络按subType做关键字,WIFI按WIFI名做关键字。对稳定的网络,因为NAT老化时间的存在,在自适应计算态的时候,暂设计以下步骤在当前心跳区间逼近出最大可用的心跳。 即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询
a)变量说明:
[MinHeart,MaxHeart]——心跳可选区间。
successHeart——当前成功心跳,初始为MinHeart
curHeart——当前心跳初始值为successHeart
heartStep——心跳增加步长
successStep——稳定期后的探测步长
经过该流程,会找到必然使心跳失败的curHeart(或者MaxHeart),为了保险起见,我们选择比前一个成功值稍微小一点的值作为后台稳定期的心跳间隔。
影响手机网络测试的因素太多,为了尽量保证测试结果的可靠性,我们使用延迟心跳测试法。在我们重新建立TCP连接后,先使用 短心跳连续成功三次,我们才认为网络相对稳定,可以使用curHeart进行一次心跳测试。图4-2显示了一次有效心跳测试过程。图4-3显示了在没有达到稳定网络环境时,我们会一直使用固定短心跳直到满足三次连续短心跳成功。
使用延迟心跳测试的好处是,可以剔除偶然失败,和网络变化较大的情况(如地铁),使测试结果相对可靠(五次延迟测试确定结论)。同时在网络波动较大的情况,使用短心跳,保证收取消息相对及时。
c)运行时的动态调整策略(已经按测算心跳稳定值后)
NAT超时值算出来后,在维持心跳的过程中的策略。
- 无网络、网络时好时坏、偶然失败、NAT超时变小:
在后台稳定期发生心跳发生失败后,我们使用延迟心跳测试法测试五次。如果有一次成功,则保持当前心跳值不变;如果五次测试全失败,重新计算合理心跳值。该过程如图4-4所示,有一点需要注意,每个新建的长连接需要先用短心跳成功维持3次后才用successHeart进行心跳。
NAT超时变大:
以周为周期,每周三将后台稳定态调至自适应计算态,使用心跳延迟法往后探测心跳间隔。
- successHeart是NAT超时临界值:
因为我们现在选择的是一个比successHeart稍小的值作为稳定值,所以在计算过程中可以避开临界值。当运营商在我们后台稳定期将NAT超时调整为我们当前计算值,那么由于我们每周会去向下探索,所以下一周探测时也可以及时调整正确。
d)冗余Sync和心跳
在用户的一些主动操作以及联网状态改变时,增加冗余Sync和心跳,确保及时收到消息。
1、当用户点亮屏幕的时候,做一次心跳。
2、当微信切换到前台时,做一次Sync。
3、联网时重建信令TCP,做一次Sync。
可能存在的风险及预防措施
DHCP租期因素:
1、问题:根据目前的测试结果显示,安卓不续约到期的IP Bug,会导致TCP连接在不确定的时间点失效,从而会导致一次心跳失败。
2、预防:统计后台稳定期的心跳成功率,上报给后台。后台可以按地区分网络监控这个指标的波动,并且后台可以根据不同的波动,动态调整某区域特定网络下可选的心跳区间。
NAT超时介绍
因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。
ANDROID手机摄像头 测心率 的原理是什么?
准确的手机检测心率软件是需要一定的手机硬件支持的。将传感器的监测功能嵌入智能手机当中,同时将手机放在身体的不同位置。用户可以将手机放在口袋或包里,可以在看视频或听一段语音对话时使用。
手机检测心率软件的项目目标是开发一个自动按照以往获得人体正常心跳和呼吸频率的方法,来恢复脉搏和呼吸波形。该种方法的准确性可与美国食品与药物管理局(FDA)批准的监测心电图(ECG)和呼吸的设备相抗衡。
扩展资料:
装有植入式心脏探测器的手机心率监测软件在诊断不明原因晕厥和心悸患者方面很有前景。这种心律失常检测技术具有重要的临床应用价值。
随着技术的进步,移植心脏检测设备小型化和多功能化逐渐发展,可以帮助患者临床,尤其是老人,行动不便,就医困难的老年人家庭社区卫生监测和早期预警和诊断和治疗,老龄化社会的进步在医疗卫生领域的管理。
文章名称:android心跳,android心跳实现方式
网页网址:http://lswzjz.com/article/dsdhggp.html