服务端设计心跳包的目的:
探知对端应用是否存活,服务端客户端都可以发心跳包,一般都是客户端发送心跳包,服务端用于判断客户端是否在线,从而对服务端内存缓存数据进行清理(玩家下线等);问题在于,通过TCP四次握手断开的设定,我们也是可以通过Socket的read方法来判断TCP连接是否断开,从而做出相应的清理内存动作,那么为什么我们还需要使用客户端发送心跳包来判断呢?
第一种判断客户端是否在线策略:
直接监控TCP传输协议的返回值,通过返回值处理应用层的存活判断
比如在C++当中
使用poll的IO复用方法时:
if(fds[i].revents &POLLERR)
if(fds[i].events &POLLDHUP)
通过上述判断可以探知TCP连接的正确性从而在服务器也关闭对应的连接
心跳网络。服务器组机器之间私网一般存在于服务器集群、多机并行时用的。
是服务器组各个机器之间传递信息用的。
比如故障转移集群服务器的心跳。集群网络是对外正常工作通讯的,心跳网络就是A\B机之间传递信息,相互验证对方是否还在正常运行用的。比如平时是A机在运行服务,A、B机之间会每隔一段时间通过心跳网询问对方是否还正常,如果A服务器宕机了,B得不到回应,就行把集群资源拿过来继续运行服务。
[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" />
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)