windows上Yii2使用workerman整套流程


1.在根目錄下新建Worker目錄 進入新建的Worker文件夾 運行 LINUX下運行 composer require workerman/workerman win 下運行 composer require workerman/workerman-for-win

2.Worker文件夾 下新建文件push.php

<?php //require_once __DIR__ .'/vendor/autoload.php'; require_once __DIR__ .'/vendor/workerman/workerman/Autoloader.php'; // require_once __DIR__ .'/vendor/workerman/workerman-for-win/Autoloader.php'; WIN下的引用 use Workerman\Worker; // // 初始化一個worker容器,監聽1234端口 $worker = new Worker('websocket://0.0.0.0:1234'); // 這里進程數必須設置為1 $worker->count = 1; // worker進程啟動后建立一個內部通訊端口 $worker->onWorkerStart = function($worker) { // 開啟一個內部端口,方便內部系統推送數據,Text協議格式 文本+換行符 $inner_text_worker = new Worker('Text://0.0.0.0:5678'); $inner_text_worker->onMessage = function($connection, $buffer) { global $worker; // $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)use($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)use($worker) { 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();


3.controllers 下添加PushController.php

<?php namespace backend\controllers; use Yii; use yii\web\Controller; class PushController extends Controller { /** * Renders the index view for the module * @return string */ public function actionWorker() { // 建立socket連接到內部推送端口 $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1); // 推送的數據,包含uid字段,表示是給這個uid推送 echo 'ERRER:'.$errno.'='.$errmsg; $data = array('uid'=>'uid1', 'percent'=>'88%測試'); // 發送數據,注意5678端口是Text協議的端口,Text協議需要在數據末尾加上換行符 fwrite($client, json_encode($data)."\n"); // 讀取推送結果 echo '$client=='.$client; echo fread($client, 8192); //return $this->render('index'); } }
4.前端測試test.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8"> <title></title> </head> <body> <h3>WebSocket協議的客戶端程序</h3> <button id="btConnect">連接到WS服務器</button> <button id="btSendAndReceive">向WS服務器發消息並接收消息</button> <button id="btClose">斷開與WS服務器的連接</button> <div id="val"></div> <script type="text/javascript"> var wsClient=null; btConnect.onclick=function(){ wsClient=new WebSocket('ws://127.0.0.1:1234'); //這個端口號和容器監聽的端口號一致 console.log(wsClient) wsClient.onopen = function(){ var uid = 'uid1'; // 表名自己是uid1 wsClient.send(uid); console.log('ws客戶端已經成功連接到服務器上') } wsClient.onmessage = function(e){ console.log('ws客戶端收到一個服務器消息:'+e.data); val.innerHTML=e.data; } } btSendAndReceive.onclick = function(){ wsClient.send('Hello Server'); wsClient.onmessage = function(e){ console.log('ws客戶端收到一個服務器消息:'+e.data); val.innerHTML=e.data; } } btClose.onclick = function(){ wsClient.close(); wsClient.onclose = function(){ console.log('到服務器的連接已經斷開'); } } </script> </body> </html>



4. 模擬過程

  在終端里執行php push.php start -d, 開啟服務, 等待客戶端(瀏覽器和php客戶端)連接

 

.瀏覽器里打開test.html, 打開控制台console, 點擊按鈕->鏈接到websocket


 
客戶端接收到php推送的消息

另開一個終端, 執行php PushController中的actionWorker方法或者瀏覽器訪問該地址, 此時再客戶端就能看到php推送過來的消息, 從而完成一次交互

 
.隨后接收到服務器返回消息


免責聲明!

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



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