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

關(guān)于Worker如何向指定Client推送消息

aaron

目前我用worker來做服務(wù)器,沒有用GatewayWorker,請問walkor大哥,如何實現(xiàn)向指定用戶推送消息?

以下是我的代碼:

$client_id = '';
$worker->onConnection( $connection ){
    global $client_id;
    $client_id = $connection->id;
};
$worker->onMessage( $connection, $data ){
global $client_id;
   foreach( $connection->worker->connections as $con ){
       if( $con->id == $client_id ){
           $con->send( $data );
           break;
       }
   }
};
13398 7 1
7個回答

aaron

注:在觸發(fā)onConnect的時候,取得ClientID,然后在onMessage內(nèi)將ClientID和用戶其他資料綁定并儲存到數(shù)據(jù)庫。上述代碼臨時寫出來的,我實際的需求是,基于worker向指定ClientID的在線用戶推送消息,上面代碼可能寫成向當前用戶推送了。

  • 暫無評論
walkor 打賞
<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';
// 初始化一個worker容器,監(jiān)聽1234端口
$worker = new Worker('websocket://workerman.net:1234');
// 進程數(shù)設(shè)置為1
$worker->count = 1;
// 新增加一個屬性,用來保存uid到connection的映射
$worker->uidConnections = array();
// 當有客戶端發(fā)來消息時執(zhí)行的回調(diào)函數(shù)
$worker->onMessage = function($connection, $data)use($worker)
{
    // 判斷當前客戶端是否已經(jīng)驗證,既是否設(shè)置了uid
    if(!isset($connection->uid))
    {
        // 沒驗證的話把第一個包當做uid(這里為了方便演示,沒做真正的驗證)
        $connection->uid = $data;
        /* 保存uid到connection的映射,這樣可以方便的通過uid查找connection,
         * 實現(xiàn)針對特定uid推送數(shù)據(jù)
         */
        $worker->uidConnections = $connection;
        return $connection->send('login success, your uid is ' . $connection->uid);
    }
    // 其它羅輯,針對某個uid發(fā)送 或者 全局廣播
    // 假設(shè)消息格式為 uid:message 時是對 uid 發(fā)送 message
    // uid 為 all 時是全局廣播
    list($recv_uid, $message) = explode(':', $data);
    // 全局廣播
    if($recv_uid == 'all')
    {
        broadcast($message);
    }
    // 給特定uid發(fā)送
    else
    {
        sendMessageByUid($recv_uid, $message);
    }
};

// 當有客戶端連接斷開時
$worker->onClose = function($connection)use($worker)
{
    global $worker;
    if(isset($connection->uid))
    {
        // 連接斷開時刪除映射
        unset($worker->uidConnections);
    }
};

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

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

// 運行所有的worker(其實當前只定義了一個)
Worker::runAll();

可以針對uid推送了,雖然是單進程,但是支持個1W在線是沒問題的

  • 暫無評論
walkor 打賞

注意只能單進程,多進程的話連接可能被分配到不同的進程,而不同的進程間是無法直接通訊的

  • leo 2015-12-16

    有沒有辦法可以實現(xiàn)多進程?

  • walkor 2015-12-16

    可以多進程,類似GatewayWorker進程模型,或者用一個代理進程轉(zhuǎn)發(fā)給其它進程

aaron

收到了,謝謝walkor,另外還有一個問題:控制客戶端close是否能夠通過上述代碼來實現(xiàn)?

  • 暫無評論
walkor 打賞

找到$connection,調(diào)用$connection->close();即可

  • 暫無評論
aaron
$worker->onMessage = function( $connection, $data ){
    if( $data數(shù)據(jù)不合法時 ){
        $connection->close();
    }
}

使用類似代碼時,貌似是全體在線用戶均會觸發(fā)close事件。

  • 暫無評論
walkor 打賞

不會

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