WorkerMan中php后端及時推送消息給客戶端


php后端及時推送消息給客戶端

原理:

1、建立一個websocket Worker,用來維持客戶端長連接

2、websocket Worker內部建立一個text Worker

3、websocket Worker 與 text Worker是同一個進程,可以方便的共享客戶端連接

4、某個獨立的php后台系統通過text協議與text Worker通訊

5、text Worker操作websocket連接完成數據推送

代碼及步驟

push.php

  

<?php

use Workerman\Worker;

require_once './Workerman/Autoloader.php';

// 初始化一個worker容器,監聽1234端口

$worker = new Worker('websocket://0.0.0.0:1234');//

  

/*

 * 注意這里進程數必須設置為1,否則會報端口占用錯誤

 * (php 7可以設置進程數大於1,前提是$inner_text_worker->reusePort=true)

 */

$worker->count = 1;

// worker進程啟動后創建一個text Worker以便打開一個內部通訊端口

$worker->onWorkerStart = function($worker)

{

    // 開啟一個內部端口,方便內部系統推送數據,Text協議格式 文本+換行符

    $inner_text_worker = new Worker('text://0.0.0.0:5678');

    $inner_text_worker->onMessage = function($connection, $buffer)

    {

        // $data數組格式,里面有uid,表示向那個uid的頁面推送數據

        $data = json_decode($buffer, true);

        $uid = $data['uid'];

        // 通過workerman,向uid的頁面推送數據

        $ret = sendMessageByUid($uid, $buffer);

        // 返回推送結果

        $connection->send($ret ? 'ok' : 'fail');

    };

    // ## 執行監聽 ##

    $inner_text_worker->listen();

};

// 新增加一個屬性,用來保存uid到connection的映射

$worker->uidConnections = array();

// 當有客戶端發來消息時執行的回調函數

$worker->onMessage = function($connection, $data)

{

    global $worker;

    // 判斷當前客戶端是否已經驗證,既是否設置了uid

    if(!isset($connection->uid))

    {

       // 沒驗證的話把第一個包當做uid(這里為了方便演示,沒做真正的驗證)

       $connection->uid = $data;

       /* 保存uid到connection的映射,這樣可以方便的通過uid查找connection,

        * 實現針對特定uid推送數據

        */

       $worker->uidConnections[$connection->uid] = $connection;

       return;

    }

};

  

// 當有客戶端連接斷開時

$worker->onClose = function($connection)

{

    global $worker;

    if(isset($connection->uid))

    {

        // 連接斷開時刪除映射

        unset($worker->uidConnections[$connection->uid]);

    }

};

  

// 向所有驗證的用戶推送數據

function broadcast($message)

{

   global $worker;

   foreach($worker->uidConnections as $connection)

   {

        $connection->send($message);

   }

}

  

// 針對uid推送數據

function sendMessageByUid($uid, $message)

{

    global $worker;

    if(isset($worker->uidConnections[$uid]))

    {

        $connection = $worker->uidConnections[$uid];

        $connection->send($message);

        return true;

    }

    return false;

}

  

// 運行所有的worker

Worker::runAll();

啟動后端服務 php push.php start -d

  

前端接收推送的js代碼

  

var ws = new WebSocket('ws://127.0.0.1:1234');

ws.onopen = function(){

    var uid = 'uid1';

    ws.send(uid);

};

ws.onmessage = function(e){

    alert(e.data);

};

后端推送消息的代碼

  

// 建立socket連接到內部推送端口

$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);

// 推送的數據,包含uid字段,表示是給這個uid推送

$data = array('uid'=>'uid1', 'percent'=>'88%');

// 發送數據,注意5678端口是Text協議的端口,Text協議需要在數據末尾加上換行符

fwrite($client, json_encode($data)."\n");

// 讀取推送結果

echo fread($client, 8192);

  

后端推送消息的代碼和push.php監聽同一個端口

push.php和前端監聽同一個websocket端口

通過后端推送消息的代碼向push.php推送數據,

push.php接受到數據后通過處理 利用websocket往前端推送數據

以上就是WorkerMan中php后端及時推送消息給客戶端的詳細內容

更多學習內容請訪問:

怎么從一名碼農成為架構師的必看知識點:目錄大全(不定期更新

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM