1、伺服器不能收到客戶端的心跳包
不知這來個心跳包傳輸模式是廣播源還是點到點呢
也許是交換機工作模式不匹配你的應用,二級交換可直接廣播,三級交換會過濾廣播的心跳包.需要三級交換配置下轉發廣播
檢查幾點,心跳包發包模式,網路互通,程序設置,交換機工作模式
2、服務端主動發送心跳包,還是客戶端發送比較好
建議客戶端發送心跳包較為合適,原因:
1、若用戶較多,服務端專發送心跳包易使服務屬器超負荷。
2、客戶端發送請求數據時可視為一次心跳包發送,節約處理速度。
3、客戶端發送失敗可立刻選擇自動退出,服務端發送需要給客戶端設置一個較長的等待時間,響應異常情況速度變慢。
當然客戶端發送容易被篡改數據等,此處需要根據實際情況考慮。
3、java的自動發送心跳包究竟是該寫在伺服器還是客戶端
socket.setKeepAlive()應該寫在客戶端,server.accept()是伺服器端的。
心跳的也有現成的,不過依賴別的類。大概貼一下,就是這么個意思。
你可以自己找找看啊。
4、服務端主動發送心跳包,還是客戶端發送比較好
一般是用來判斷對方(設備,進程或其它網元)是否正常動行,一般採用定時發送簡單的通訊包,如果在指定時間段內未收到對方響應,則判斷對方已經當掉。用於檢測TCP的異常斷開。一般是用來判斷對方(設備,進程或其它網元)是否正常動行,一般採用定時發送簡單的通訊包,如果在指定時間段內未收到對方響應,則判斷對方已經當掉。用於檢測TCP的異常斷開。基本原因是伺服器端不能有效的判斷客戶端是否在線也就是說,伺服器無法區分客戶端是長時間在空閑,還是已經掉線的情況.所謂的心跳包就是客戶端定時發送簡單的信息給伺服器端告訴它我還在而已。代碼就是每隔幾分鍾發送一個固定信息給服務端,服務端收到後回復一個固定信息如果服務端幾分鍾內沒有收到客戶端信息則視客戶端斷開。比如有些通信軟體長時間不使用,要想知道它的狀態是在線還是離線就需要心跳包,定時發包收包。發包方:可以是客戶也可以是服務端,看哪邊實現方便合理。一般是客戶端。伺服器也可以定時輪詢發心跳下去。一般來說,出於效率的考慮,是由客戶端主動向伺服器端發包,而不是就是在客戶端和伺服器間定時通知對方自己狀態的一個自己定義的命令字,按照一定的時間間隔發送,類似於心跳,所以叫做心跳包。 就是定時發送給對方一個數據包,告訴對方自己還在維護對話,同時獲得返回的數據,判斷對方是否在會話中。客戶端每隔一段時間發一個包,使用TCP的,用send發,使用UDP的,用sendto發,伺服器收到後,就知道當前客戶端還處於「活著」的狀態,否則,如果隔一定時間未收到這樣的包,則伺服器認為客戶端已經斷開,進行相應的客戶端斷開邏輯處理。
5、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);
List<RunningTaskInfo> 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);
List<RunningTaskInfo> 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" />
6、用了心跳包,客戶端12秒已發送,伺服器判斷15秒超時,socket連接2-3分鍾就異常掉線,哪的事?
給你點建議,把接受用戶連接請求的線程和處理用戶消息的線程分開給你個參考吧
using System;7、如何向伺服器發送心跳包
這個你要和伺服器端協商介面 然後在ios這邊用線程或者nstimer來調用發送心跳的介面
/向伺服器發送心跳包 sendHeartbeatPackage(mRestMsg); count += 1; } Thread.sleep(1000 * 3); } catch (InterruptedException e)
8、伺服器怎麼判斷心跳包?
用sendUrgentData這個來判斷服務端是否異常關閉
想實現自動連接服務端,如果用
socket = new Socket("192.168.1.4",1821);
socket.connect();
只有每次去new創建這個sock對象,因為只有sock對象創建好了才由輸入輸出流
目前的實現方式就是,
1.在原有的基礎上,再開多一個線程,專門負責發送心跳,
2.先睡眠500毫秒,
3.用socket.sendUrgentData(FF),給服務端,
4.如果服務端異常關閉的話,我就捕捉這個異常。。。
5.循環
心跳的意思就是每隔一段時間,客戶端給伺服器發一段消息:
1、客戶端:伺服器,我還活著,你死了沒
2、伺服器:客戶端,我知道你還活著這個信息,我已經記錄下來了,同時告訴你我也還活著
更多問題到問題求助專區http://bbs.hounwang.com/