<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 1\. 什么是心跳 其實簡單的說就是:客戶端隔一段時間就給服務端發送消息,用來告訴服務端這個連接沒有斷,是正常的,從而維護長連接的持久性。 如果不加心跳包,有的服務器節點(防火墻)會自動把一定時間之內沒有數據交互的連接給斷掉;而且這中間指不定會有什么亂七八糟的比如機器斷電、網線拔出這些幺蛾子出現導致客戶端斷線。 但是類似斷網這種**極端情況**導致客戶端斷開連接,服務端是不知道的。因為客戶端在正常情況下主動斷開會向服務端發送一個tcp的fin包。 > 什么是FIN包? > FIN包表示發送端已經達到數據末尾,也就是說雙方的數據傳送完成,沒有數據可以傳送了。 > 發送FIN標志 位的TCP數據包后,連接將被斷開。 > 這個標志的數據包也經常被用于進行端口掃描。 然而極端情況下,客戶端沒有機會發這個包,就會導致服務端并不知道客戶端斷掉了。 # 2\. 長連接必須加心跳 長連接,只要是長連接,長時間不通訊肯定會被防火墻干掉然后斷開,服務在非可控情況下斷開是非常不好的情況;所以長連接無論如何都要加上心跳包。 # 3\. 心跳實例 接下來以workerman建立websocket連接為實例。 ## 3.1 前端JavaScript代碼 在onopen連接建立的時候,定義一個定時器,每10秒鐘發送一個包,包的內容隨意。 ~~~ var ws = new WebSocket("ws://www.goozp.com"); //連接websocket ws.onopen = function () { setInterval(function () { ws.send('Hello!'); }, 10000) }; ~~~ 一般發送心跳包的間隔在60秒以內。 ## 3.2 Workerman中處理斷線 此處參考:[官方文檔:心跳](http://doc.workerman.net/315282 "官方文檔:心跳") 可以先定義一些常量在之后用到,方便配置: ~~~ define('HEARTBEAT_TIME', 30); // 定義一個心跳間隔30秒 define('CHECK_HEARTBEAT_TIME', 1); // 檢查連接的間隔時間 ~~~ 當接收到信息時,我們就記錄下接收到信息的時間: ~~~ $worker->onMessage = function($connection, $msg) { // 給connection臨時設置一個lastMessageTime屬性,用來記錄上次收到消息的時間 $connection->lastMessageTime = time(); // TODO 其它業務邏輯... }; ~~~ 在進程啟動后設置一個定時器,每隔一段時間遍歷一遍當前worker的所有連接 ~~~ // 進程啟動后設置一個每秒運行一次的定時器 $worker->onWorkerStart = function($worker) { Timer::add(CHECK_HEARTBEAT_TIME, function()use($worker){ $time_now = time(); foreach($worker->connections as $connection) { // 有可能該connection還沒收到過消息,則lastMessageTime設置為當前時間 if (empty($connection->lastMessageTime)) { $connection->lastMessageTime = $time_now; continue; } // 上次通訊時間間隔大于心跳間隔,則認為客戶端已經下線,關閉連接 if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) { $connection->close(); } } }); }; ~~~ 這樣,結合前端的心跳包,我們就可以做到維持連接的長久,以及踢出設置時間段內未使用的廢棄連接。 >好文轉載,此章節轉載地址:[咖啡與代碼](https://www.goozp.com/category/workerman) -(原作者如有要求,會立馬下架此章節)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看