国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

求助WebSocket opening handshake timed out和dtruss跟蹤

beijingde

1,最近在做一個實時監(jiān)控項目,用到了html5的websocket。場景如下:
點擊設備列表,進入某個設備詳情頁面,監(jiān)控這個設備的運行狀況,實時更新一些設備運行狀態(tài)參數(shù)。

2,前端代碼如下:

// 省略...
const socket = new WebSocket(server);

socket.addEventListener('open', function(e) {
    socket.send(該設備id);
});

socket.addEventListener('message', function(e) {
    const data = e.data;

    更新設備信息(data);
});

socket.addEventListener('close', function(e) {
    console.log('websockt連接已關(guān)閉');
});

socket.addEventListener('error', function(e) {
    alert("websockt連接發(fā)生錯誤,請刷新頁面重試!");
});

// 省略...

3,后端我用的php的wokerman(一個php sokcet服務框架)提供的一個websocket服務用來測試(我目前做前端開發(fā),用這個workerman只是用來測試)。

// 心跳間隔25秒
define('HEARTBEAT_TIME', 25);

$ws_worker = new Worker("websocket://0.0.0.0:9668");

// 8 processes
$ws_worker->count = 8;

// 進程啟動后設置一個每秒運行一次的定時器
$ws_worker->onWorkerStart = function($worker) {
    Timer::add(1, function()use($worker){
        $time_now = time();
        foreach($worker->connections as $connection) {
            // 有可能該connection還沒收到過消息,則lastMessageTime設置為當前時間
            if (empty($connection->lastMessageTime)) {
                $connection->lastMessageTime = $time_now;
                continue;
            }
            // 上次通訊時間間隔大于心跳間隔,則認為客戶端已經(jīng)下線,關(guān)閉連接
            if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
                $connection->close();
            }
        }
    });
};

// Emitted when data received
$ws_worker->onMessage = function ($connection, $data) {

    // 給connection臨時設置一個lastMessageTime屬性,用來記錄上次收到消息的時間
    $connection->lastMessageTime = time();

    while (true) {
        $connection->send(根據(jù)接收到的客戶端的$data發(fā)送要發(fā)送的消息);
        usleep(1000000); // 睡1秒
    }
};

4,現(xiàn)象:
我發(fā)現(xiàn)如果刷新設備詳情頁面8次以上(這個次數(shù)正好和后端代碼中設置的wokerman的進程數(shù)相等),客戶端就會連接不上后端的socket服務,一直pending,直到提示:WebSocket opening handshake timed out。而wokerman的運行狀態(tài)則為:

圖片
5,問題:
我想問下我的代碼哪里出了問題,是前端js代碼或業(yè)務邏輯有問題還是后端php代碼或業(yè)務有問題。
謝謝。

ps:
前后端代碼都是跑在本地上,mac os。我看了論壇上和workerman手冊上提到可以用strace來跟蹤進程,但mac上只有dtruss(貌似是調(diào)用的dtrace)可以用,我跟蹤了一個busy的進程 sudo dtruss -p 24368發(fā)現(xiàn):

圖片
但我看不太明白打印的這些都是什么,不知道問題處出在哪里。

10987 1 0
1個回答

xiuwang

while (true) {
$connection->send(根據(jù)接收到的客戶端的$data發(fā)送要發(fā)送的消息);
usleep(1000000); // 睡1秒
}

業(yè)務代碼死循環(huán)了,這樣你的代碼一直在死循環(huán)在while (true) {}里運行,其它代碼都執(zhí)行不到的,包括onMessage的代碼,包括workerman框架的代碼都執(zhí)行不到,所以完全不工作了。C/C++/java等語言都是,死循環(huán)是大忌。

  • beijingde 2018-02-05

    謝謝,我明白了。之前我對后端往前端推送消息的邏輯沒想清除,以為把發(fā)送消息的代碼放在一個死循環(huán)里一直發(fā)送就可以了,現(xiàn)在我把代碼改了,前端定時往后端發(fā)送消息,后端監(jiān)聽前端的消息,根據(jù)前端發(fā)送的消息推送對應的消息,這樣某個進程就不會一直處于busy狀態(tài)了。

年代過于久遠,無法發(fā)表回答
??