后臺開啟一個線程一直運行,每隔1分鐘左右發(fā)送一個心跳報文給服務(wù)器,以確保時刻跟服務(wù)器鏈接。若超過3次服務(wù)器未對客戶端發(fā)送的心跳報文做出回應(yīng)則重新鏈接。 如果這么作的話,必須確保和服務(wù)器達成一定的應(yīng)用層協(xié)議。
成都創(chuàng)新互聯(lián)服務(wù)項目包括姚安網(wǎng)站建設(shè)、姚安網(wǎng)站制作、姚安網(wǎng)頁制作以及姚安網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,姚安網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到姚安省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
[圖文]2013年2月2日 - //向服務(wù)器發(fā)送心跳包 sendHeartbeatPackage(...點擊復(fù)制鏈接 與好友分享!回本站首頁 分享到:...Java程序移植到android上問題解決小結(jié)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)??
{??
//判斷應(yīng)用是否在運行???
ActivityManager?am?=?(ActivityManager)?getSystemService(Context.ACTIVITY_SERVICE);??
ListRunningTaskInfo?list?=?am.getRunningTasks(3);??
for?(RunningTaskInfo?info?:?list)??
{??
if?(info.topActivity.getPackageName().equals("org.yhn.demo"))??
{??
//通知應(yīng)用,顯示提示“連接不到服務(wù)器”???
Intent?intent?=?new?Intent("org.yhn.demo");??
intent.putExtra("msg",?true);??
sendBroadcast(intent);??
break;??
}??
}??
isTip?=?false;??
}??
}??
if?(mRestMsg?!=?""??mRestMsg?!=?null)??
{??
//向服務(wù)器發(fā)送心跳包???
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();??
//?發(fā)送請求???
HttpResponse?httpResponse?=?null;??
try??
{??
httpResponse?=?httpClient.execute(httpGet);??
}??
catch?(Exception?e)??
{??
e.printStackTrace();??
}??
if?(httpResponse?==?null)??
{??
return;??
}??
//?處理返回結(jié)果???
final?int?responseCode?=?httpResponse.getStatusLine().getStatusCode();??
if?(responseCode?==?HttpStatus.SC_OK)??
{??
//只要服務(wù)器有回應(yīng)就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");??
//從本地讀取服務(wù)器的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)
{
//判斷應(yīng)用是否在運行
ActivityManager?am?=?(ActivityManager)?getSystemService(Context.ACTIVITY_SERVICE);
ListRunningTaskInfo?list?=?am.getRunningTasks(3);
for?(RunningTaskInfo?info?:?list)
{
if?(info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知應(yīng)用,顯示提示“連接不到服務(wù)器”
Intent?intent?=?new?Intent("org.yhn.demo");
intent.putExtra("msg",?true);
sendBroadcast(intent);
break;
}
}
isTip?=?false;
}
}
if?(mRestMsg?!=?""??mRestMsg?!=?null)
{
//向服務(wù)器發(fā)送心跳包
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();
//?發(fā)送請求
HttpResponse?httpResponse?=?null;
try
{
httpResponse?=?httpClient.execute(httpGet);
}
catch?(Exception?e)
{
e.printStackTrace();
}
if?(httpResponse?==?null)
{
return;
}
//?處理返回結(jié)果
final?int?responseCode?=?httpResponse.getStatusLine().getStatusCode();
if?(responseCode?==?HttpStatus.SC_OK)
{
//只要服務(wù)器有回應(yīng)就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");
//從本地讀取服務(wù)器的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"?/
在支持GCM的設(shè)備上,主要靠GCM來激活WhatsApp,WhatsApp啟動后,會建立一個與服務(wù)器的長連接,直接通過此長連接發(fā)送Push消息,這個長連接10分鐘無消息就會主動斷掉,且這十分鐘內(nèi)不做心跳,斷掉后WhatsApp客戶端和它的服務(wù)器不再有連接。當(dāng)有消息時候,服務(wù)器發(fā)現(xiàn)沒有長連接會發(fā)送GCM消息,手機收到GCM消息后,會重新建立長連接來收取消息,10分鐘無消息會再斷開,如此循環(huán)。
IM即時通訊開發(fā)如何實現(xiàn)Android版智能心跳機制。
大體思路
a)延遲心跳測試法:這是測試結(jié)果準(zhǔn)確的前提保障,我們認為長連接建立后連續(xù)三次成功的短心跳就可以很大程度的保證下一次心跳環(huán)境是正常的。
b)成功一次認定,失敗連續(xù)累積認定:成功是絕對的,連續(xù)失敗多次才可能是失敗。
c)臨界值避免:我們使用比計算出的心跳稍微小一點的值做為穩(wěn)定心跳避免臨界值。
d)動態(tài)調(diào)整:即使在一次完整的智能心跳計算過程中,我們沒有找到最好的值,我們還有機會來進行校正。
方案需考慮到影響連接壽命的思素
在Android下,不管是GCM,還是微信,都是通過TCP長連接來進行消息收發(fā)的,TCP長連接存活,消息收發(fā)就及時,所以要對影響TCP連接壽命的因素進行研究。
1、NAT超時
大部分移動無線網(wǎng)絡(luò)運營商都在鏈路一段時間沒有數(shù)據(jù)通訊時,會淘汰 NAT 表中的對應(yīng)項,造成鏈路中斷(NAT超時的更多描述見附錄9.1)。NAT超時是影響TCP連接壽命的一個重要因素(尤其是國內(nèi)),所以客戶端自動測算NAT超時時間,來動態(tài)調(diào)整心跳間隔,是一個重要的優(yōu)化點。
2、DHCP的租期 (lease time)
目前測試發(fā)現(xiàn)安卓系統(tǒng)對DHCP的處理有Bug,DHCP租期到了不會主動續(xù)約并且會繼續(xù)使用過期IP,這個問題會造成TCP長連接偶然的斷連。(租期問題的具體描述見附錄9.2)。
3、網(wǎng)絡(luò)狀態(tài)變化
手機網(wǎng)絡(luò)和WIFI網(wǎng)絡(luò)切換、網(wǎng)絡(luò)斷開和連上等情況有網(wǎng)絡(luò)狀態(tài)的變化,也會使長連接變?yōu)闊o效連接,需要監(jiān)聽響應(yīng)的網(wǎng)絡(luò)狀態(tài)變化事件,重新建立Push長連接。
心跳范圍選擇
1、前后臺區(qū)分處理:
為了保證微信收消息及時性的體驗,當(dāng)微信處于前臺活躍狀態(tài)時,使用固定心跳。微信進入后臺(或者前臺關(guān)屏)時,先用幾次最小心跳維持長鏈接。然后進入后臺自適應(yīng)心跳計算。這樣做的目的是盡量選擇用戶不活躍的時間段,來減少心跳計算可能產(chǎn)生的消息不及時收取影響。
2、后臺自適應(yīng)心跳選擇區(qū)間:
可根據(jù)自身產(chǎn)品的特點選擇合適的心跳范圍。
自適應(yīng)心跳算法量化描述
因為每個網(wǎng)絡(luò)的NAT時間可能不一致。所以需要區(qū)分計算,數(shù)據(jù)網(wǎng)絡(luò)按subType做關(guān)鍵字,WIFI按WIFI名做關(guān)鍵字。對穩(wěn)定的網(wǎng)絡(luò),因為NAT老化時間的存在,在自適應(yīng)計算態(tài)的時候,暫設(shè)計以下步驟在當(dāng)前心跳區(qū)間逼近出最大可用的心跳。 即時通訊聊天軟件app開發(fā)可以加蔚可云的v:weikeyun24咨詢
a)變量說明:
[MinHeart,MaxHeart]——心跳可選區(qū)間。
successHeart——當(dāng)前成功心跳,初始為MinHeart
curHeart——當(dāng)前心跳初始值為successHeart
heartStep——心跳增加步長
successStep——穩(wěn)定期后的探測步長
經(jīng)過該流程,會找到必然使心跳失敗的curHeart(或者MaxHeart),為了保險起見,我們選擇比前一個成功值稍微小一點的值作為后臺穩(wěn)定期的心跳間隔。
影響手機網(wǎng)絡(luò)測試的因素太多,為了盡量保證測試結(jié)果的可靠性,我們使用延遲心跳測試法。在我們重新建立TCP連接后,先使用??短心跳連續(xù)成功三次,我們才認為網(wǎng)絡(luò)相對穩(wěn)定,可以使用curHeart進行一次心跳測試。圖4-2顯示了一次有效心跳測試過程。圖4-3顯示了在沒有達到穩(wěn)定網(wǎng)絡(luò)環(huán)境時,我們會一直使用固定短心跳直到滿足三次連續(xù)短心跳成功。
使用延遲心跳測試的好處是,可以剔除偶然失敗,和網(wǎng)絡(luò)變化較大的情況(如地鐵),使測試結(jié)果相對可靠(五次延遲測試確定結(jié)論)。同時在網(wǎng)絡(luò)波動較大的情況,使用短心跳,保證收取消息相對及時。
c)運行時的動態(tài)調(diào)整策略(已經(jīng)按測算心跳穩(wěn)定值后)
NAT超時值算出來后,在維持心跳的過程中的策略。
-??無網(wǎng)絡(luò)、網(wǎng)絡(luò)時好時壞、偶然失敗、NAT超時變小:
在后臺穩(wěn)定期發(fā)生心跳發(fā)生失敗后,我們使用延遲心跳測試法測試五次。如果有一次成功,則保持當(dāng)前心跳值不變;如果五次測試全失敗,重新計算合理心跳值。該過程如圖4-4所示,有一點需要注意,每個新建的長連接需要先用短心跳成功維持3次后才用successHeart進行心跳。
NAT超時變大:
以周為周期,每周三將后臺穩(wěn)定態(tài)調(diào)至自適應(yīng)計算態(tài),使用心跳延遲法往后探測心跳間隔。
-??successHeart是NAT超時臨界值:
因為我們現(xiàn)在選擇的是一個比successHeart稍小的值作為穩(wěn)定值,所以在計算過程中可以避開臨界值。當(dāng)運營商在我們后臺穩(wěn)定期將NAT超時調(diào)整為我們當(dāng)前計算值,那么由于我們每周會去向下探索,所以下一周探測時也可以及時調(diào)整正確。
d)冗余Sync和心跳
在用戶的一些主動操作以及聯(lián)網(wǎng)狀態(tài)改變時,增加冗余Sync和心跳,確保及時收到消息。
1、當(dāng)用戶點亮屏幕的時候,做一次心跳。
2、當(dāng)微信切換到前臺時,做一次Sync。
3、聯(lián)網(wǎng)時重建信令TCP,做一次Sync。
可能存在的風(fēng)險及預(yù)防措施
DHCP租期因素:
1、問題:根據(jù)目前的測試結(jié)果顯示,安卓不續(xù)約到期的IP Bug,會導(dǎo)致TCP連接在不確定的時間點失效,從而會導(dǎo)致一次心跳失敗。
2、預(yù)防:統(tǒng)計后臺穩(wěn)定期的心跳成功率,上報給后臺。后臺可以按地區(qū)分網(wǎng)絡(luò)監(jiān)控這個指標(biāo)的波動,并且后臺可以根據(jù)不同的波動,動態(tài)調(diào)整某區(qū)域特定網(wǎng)絡(luò)下可選的心跳區(qū)間。
NAT超時介紹
因為 IP v4 的 IP 量有限,運營商分配給手機終端的 IP 是運營商內(nèi)網(wǎng)的 IP,手機要連接 Internet,就需要通過運營商的網(wǎng)關(guān)做一個網(wǎng)絡(luò)地址轉(zhuǎn)換(Network Address Translation,NAT)。簡單的說運營商的網(wǎng)關(guān)需要維護一個外網(wǎng) IP、端口到內(nèi)網(wǎng) IP、端口的對應(yīng)關(guān)系,以確保內(nèi)網(wǎng)的手機可以跟 Internet 的服務(wù)器通訊。
準(zhǔn)確的手機檢測心率軟件是需要一定的手機硬件支持的。將傳感器的監(jiān)測功能嵌入智能手機當(dāng)中,同時將手機放在身體的不同位置。用戶可以將手機放在口袋或包里,可以在看視頻或聽一段語音對話時使用。
手機檢測心率軟件的項目目標(biāo)是開發(fā)一個自動按照以往獲得人體正常心跳和呼吸頻率的方法,來恢復(fù)脈搏和呼吸波形。該種方法的準(zhǔn)確性可與美國食品與藥物管理局(FDA)批準(zhǔn)的監(jiān)測心電圖(ECG)和呼吸的設(shè)備相抗衡。
擴展資料:
裝有植入式心臟探測器的手機心率監(jiān)測軟件在診斷不明原因暈厥和心悸患者方面很有前景。這種心律失常檢測技術(shù)具有重要的臨床應(yīng)用價值。
隨著技術(shù)的進步,移植心臟檢測設(shè)備小型化和多功能化逐漸發(fā)展,可以幫助患者臨床,尤其是老人,行動不便,就醫(yī)困難的老年人家庭社區(qū)衛(wèi)生監(jiān)測和早期預(yù)警和診斷和治療,老齡化社會的進步在醫(yī)療衛(wèi)生領(lǐng)域的管理。
本文名稱:android心跳,android心跳實現(xiàn)方式
文章轉(zhuǎn)載:http://m.rwnh.cn/article18/dsdhggp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、動態(tài)網(wǎng)站、服務(wù)器托管、電子商務(wù)、建站公司、手機網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)