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

使用start_worker的onMessage無法執(zhí)行內(nèi)部函數(shù)方法

vzainet

@walkor大神,非常感謝大神這么晚還這么快速的回復(fù),謝謝了!也特別感謝大神們開發(fā)出workerman這么優(yōu)秀的框架,給我們廣大開發(fā)者帶來的極大便利,是碼農(nóng)們的福音!

我對問題重新做了下編輯,同時也把代碼demo直接發(fā)上來,還請大神能給予指導(dǎo),問題還是onmessage回調(diào)里去實現(xiàn)服務(wù)端給客戶端發(fā)送消息時候,無法觸達,代碼如下:

use \Workerman\Worker;
use \Workerman\Timer;
use \Workerman\Connection\UdpConnection;

// 自動加載類
require_once __DIR__ . '/../../vendor/autoload.php';

$worker = new Worker('udp://0.0.0.0:6000');
// worker名稱
$worker->name = 'XMC-UDP-Worker';
// Worker進程數(shù)量
/*
 * 注意這里進程數(shù)必須設(shè)置為1,否則會報端口占用錯誤
 * (php 7可以設(shè)置進程數(shù)大于1,前提是$inner_text_worker->reusePort=true)
 */
$worker->count = 1;
$worker->uids = [];

//啟動內(nèi)部通訊
$worker->onWorkerStart = function ($worker) {
    // 開啟一個內(nèi)部端口,方便內(nèi)部系統(tǒng)推送數(shù)據(jù),Text協(xié)議格式 文本+換行符
    $inner_text_worker = new Worker('text://0.0.0.0:5678');
    $inner_text_worker->onMessage = function ($connection, $buffer) {
        // $data數(shù)組格式,里面有uid,表示向那個uid的頁面推送數(shù)據(jù)
        $data = json_decode($buffer, true);
        $uid = intval($data['uid']);
        // 通過workerman,向uid的頁面推送數(shù)據(jù)
        $ret = sendMessageByUid($uid, $data['msg']);
        // 返回推送結(jié)果
        $connection->send($ret ? 'ok' : 'fail');
    };
    // ## 執(zhí)行監(jiān)聽 ##
    $inner_text_worker->listen();
};

//監(jiān)聽接收消息
$worker->onMessage = function ($connection, $message) {
    global $worker;
    if (!isset($connection->uid)) {
        $ip_arr = explode('.', $connection->getRemoteIp());
        ///$port = $connection->getRemotePort();
        $ip = intval(end($ip_arr));
        $connection->uid = $ip;
        $worker->uids[$connection->uid] = $connection;
    }
    //$client_id這里為了測試直接寫死為一個客戶端IP
    $client_id=109;
    $client = stream_socket_client('tcp://0.0.0.0:5678', $errno, $errmsg, 1);
    // 推送的數(shù)據(jù),包含uid字段,表示是給這個uid推送
    $data = json_encode(['uid' => $client_id, 'msg' => 'test']);
    // 發(fā)送數(shù)據(jù),注意5678端口是Text協(xié)議的端口,Text協(xié)議需要在數(shù)據(jù)末尾加上換行符
    fwrite($client, $data . "\n");
    //echo fread($client, 8192);
};

// 向所有驗證的用戶推送數(shù)據(jù)
function broadcast($message)
{
    global $worker;
    foreach ($worker->uids as $connection) {
        $connection->send($message);
    }
};

// 針對uid推送數(shù)據(jù)
function sendMessageByUid($uid, $message)
{
    global $worker;
    if (isset($worker->uids[$uid])) {
        $connection = $worker->uids[$uid];
        $connection->send($message);
    }
};

// 如果不是在根目錄啟動,則運行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}
2159 4 0
4個回答

walkor 打賞

require_once 只會加載一次,下次再次執(zhí)行require_once 時這個文件就不會加載了,所以里面的業(yè)務(wù)邏輯就不會再觸發(fā)了。
require_once 改成 require 試下

  • vzainet 2022-01-05

    好的,我先試試看,謝謝walkor !

  • vzainet 2022-01-05

    walkor,好像還并不是這問題,我直接把push.php推送消息給客戶端的代碼直接寫到onmessage回調(diào)里,客戶端也還是收不到,這個是和內(nèi)部通訊實現(xiàn)方式有關(guān)系么?還是需要其他手段來實現(xiàn)推送呢?

  • vzainet 2022-01-05

    但是我使用普通的php文件,或直接用push.php去推送,就是可以的,說明內(nèi)部端口那應(yīng)該沒問題,問題就是onmessage回調(diào)去做推送就存在問題!

  • walkor 2022-01-05

    寫個能重現(xiàn)問題的精簡的demo吧。沒代碼沒辦法定位啊。我又不是神,能預(yù)知你哪里寫了bug ??

  • vzainet 2022-01-06

    walkor 大神,我編輯了下問題,把代碼都貼上了,煩請您再幫忙指導(dǎo)下,十分感謝!

walkor 打賞

$worker->uids[$connection->uid] = $connection;
這里不對,應(yīng)該改成
$worker->uids[$connection->id] = $connection;

還有你的uid寫死了只給109發(fā)數(shù)據(jù),那么

$connection->uid = $ip;
$worker->uids[$connection->uid] = $connection;

也要寫死,$connection->uid = 109; 才對。

另外uid要做個定時器,將長時間不活躍的$connection 執(zhí)行關(guān)閉,然后從$worker->uids里刪除,否則這個connection一直占用內(nèi)存,會導(dǎo)致內(nèi)存泄漏。

最后,udp是無連接的并且無法保證數(shù)據(jù)一定能推送到客戶端,客戶端及客戶端所在網(wǎng)關(guān)可能隨時會關(guān)閉udp臨時端口。一般外網(wǎng)udp超過1分鐘,udp可能就無法發(fā)送到客戶端了。

walkor 打賞

我寫死 $client_id=1; 了,本地127.0.0.1測試沒問題。
客戶端代碼

<?php

use \Workerman\Worker;
use \Workerman\Connection\AsyncUdpConnection;

require_once __DIR__ . '/../../vendor/autoload.php';
$worker = new Worker();

$worker->onWorkerStart = function ($worker) {
   $con = new AsyncUdpConnection('udp://127.0.0.1:6000');
   $con->onMessage = function($con, $data){
      var_dump($data);
   };
   $con->onConnect = function($con){$con->send(1);};
   $con->connect();
};

if (!defined('GLOBAL_START')) {
    Worker::runAll();
}

結(jié)果:
截圖

  • vzainet 2022-01-06

    好呢,我再仔細(xì)研讀下你的思路和寫法,調(diào)測看下,再次表示感謝!

vzainet

@walkor,目前測試是每次重啟服務(wù)后,第1次能發(fā)送消息到客戶端,再次發(fā)送就無法送達呢(也就是后面的發(fā)送消息給客戶端執(zhí)行無效了),這個是哪需要做特殊處理不?代碼是這樣寫的:

//監(jiān)聽接收消息
$worker->onMessage = function (UdpConnection $connection, $message) {
    global $worker;
    //設(shè)置連接
    $connection->uid = 109;
    if (isset($worker->uids[$connection->uid])) {
        $worker->uids[$connection->uid]->close();
    }
    $worker->uids[$connection->uid] = $connection;
    //發(fā)送消息給客戶端
    $client = stream_socket_client('tcp://0.0.0.0:5678', $errno, $errmsg, 1);
    $data = json_encode(['uid' => 109, 'msg' => 'TASK[109 001]CRC[2c4c]']);
    fwrite($client, $data . "\n");
}
  • walkor 2022-01-06

    加了個定時器,測試沒問題

    <?php
    
    use \Workerman\Worker;
    use \Workerman\Timer;
    use \Workerman\Connection\AsyncUdpConnection;
    
    require_once __DIR__ . '/../../vendor/autoload.php';
    $worker = new Worker();
    
    $worker->onWorkerStart = function ($worker) {
       $con = new AsyncUdpConnection('udp://127.0.0.1:6000');
       $con->onMessage = function($con, $data){
          var_dump($data);
       };
       $con->onConnect = function($con){
          Timer::add(5, function()use($con) {
             $con->send(2);
          });
          $con->send(1);
       };
       $con->connect();
    };
    
    if (!defined('GLOBAL_START')) {
        Worker::runAll();
    }

    截圖

  • vzainet 2022-01-06

    大神,這個是客戶端的代碼么?我寫的只有服務(wù)端程序哦,目前場景是手機APP里有個條形碼,然后線下有個硬件掃碼器,用來掃碼手機APP的條形碼,掃碼成功就掃碼器那會發(fā)送消息給UDP服務(wù)器,服務(wù)器onmessage進行回調(diào)后,就啟動發(fā)送消息指令給某個客戶端哈!這個我實在不知道要改哪塊的代碼了,因為這個動作是掃碼器客戶端發(fā)送消息給服務(wù)器后觸發(fā)的呢!

  • walkor 2022-01-06

    對,客戶端。

  • vzainet 2022-01-06

    服務(wù)端沒有辦法解決這個第2次請求不觸發(fā)的問題不?謝謝啊

  • walkor 2022-01-06

    服務(wù)端應(yīng)該沒問題,你看我發(fā)的截圖,已經(jīng)觸發(fā)多次了

  • vzainet 2022-01-06

    現(xiàn)在就是線下掃碼器回傳信息給服務(wù)端,第一次可以觸發(fā),往下就不觸發(fā)發(fā)送消息給指定客戶端了,搞了好幾天,百思不得其解哈,實在是不知道問題出在哪?如果我不走這個服務(wù)端程序,用普通的php去調(diào)用就完全正常,卡就卡在服務(wù)端onmessage這個點上來,感謝walkor不厭其煩的回復(fù)和解答哈,再次感謝!

  • vzainet 2022-01-06

    會不會跟線下硬件掃碼器有關(guān)系呢?但是掃碼器的UDP數(shù)據(jù)是發(fā)送上來了,服務(wù)端onmessage里也收到了,但是就是不走觸發(fā)發(fā)送消息給客戶端的指令。

  • walkor 2022-01-06

    不客氣。建議你用我上面workerman做的udp客戶端代替真實客戶端來測試,沒問題再用真實客戶端測試。
    另外可以配合抓包工具看下服務(wù)端是否有發(fā)送udp給客戶端。

  • walkor 2022-01-06

    多打日志看下吧,看下代碼走大哪個分支??蛻舳薸d都打印出來,看下id對不對,看下對應(yīng)的客戶端是否和服務(wù)端發(fā)器過udp請求,對應(yīng)的客戶端connection是否是存在的。感覺這種問題打日志抓包很好定位。

  • vzainet 2022-01-06

    呃呃,忘了這塊調(diào)試日志了,我好好按照您說的仔細(xì)檢查一下,務(wù)必揪出元兇!感謝大神哈,多次發(fā)問實在打攪了!

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