为什么在服务端设计当中需要考虑心跳

为什么在服务端设计当中需要考虑心跳,第1张

的检测,清除死连接,即使在没有数据来往的时候,TCP也就可以(在启动TCP这个功能的前提下)自动发包检测是否连接正常,这个不需要我们处理。

服务端设计心跳包的目的:

探知对端应用是否存活,服务端客户端都可以发心跳包,一般都是客户端发送心跳包,服务端用于判断客户端是否在线,从而对服务端内存缓存数据进行清理(玩家下线等);问题在于,通过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" />


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/496788.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-06-15
下一篇2023-06-15

发表评论

登录后才能评论

评论列表(0条)

    保存