1. 程式人生 > >基於workerman的叢集推送例子

基於workerman的叢集推送例子

本文轉自:http://doc3.workerman.net/component/channel-examples.html

例子1

(要求Workerman版本>=3.3.0)

基於Worker的多程序(分散式叢集)推送系統

start.php

<?php
use Workerman\Worker;
require_once './Workerman/Autoloader.php';
require_once './Channel/src/Server.php';
require_once './Channel/src/Client.php';

// 初始化一個Channel服務端
$channel_server
= new Channel\Server('0.0.0.0', 2206); // websocket服務端 $worker = new Worker('websocket://0.0.0.0:4236'); $worker->count=2; $worker->name = 'pusher'; $worker->onWorkerStart = function($worker) { // Channel客戶端連線到Channel服務端 Channel\Client::connect('127.0.0.1', 2206); // 以自己的程序id為事件名稱 $event_name
= $worker->id; // 訂閱worker->id事件並註冊事件處理函式 Channel\Client::on($event_name, function($event_data)use($worker){ $to_connection_id = $event_data['to_connection_id']; $message = $event_data['content']; if(!isset($worker->connections[$to_connection_id])) { echo
"connection not exsits\n"; return; } $to_connection = $worker->connections[$to_connection_id]; $to_connection->send($message); }); // 訂閱廣播事件 $event_name = '廣播'; // 收到廣播事件後向當前程序內所有客戶端連線傳送廣播資料 Channel\Client::on($event_name, function($event_data)use($worker){ $message = $event_data['content']; foreach($worker->connections as $connection) { $connection->send($message); } }); }; $worker->onConnect = function($connection)use($worker) { $msg = "workerID:{$worker->id} connectionID:{$connection->id} connected\n"; echo $msg; $connection->send($msg); }; // 用來處理http請求,向任意客戶端推送資料,需要傳workerID和connectionID $http_worker = new Worker('http://0.0.0.0:4237'); $http_worker->name = 'publisher'; $http_worker->onWorkerStart = function() { Channel\Client::connect('127.0.0.1', 2206); }; $http_worker->onMessage = function($connection, $data) { $connection->send('ok'); if(empty($_GET['content'])) return; // 是向某個worker程序中某個連線推送資料 if(isset($_GET['to_worker_id']) && isset($_GET['to_connection_id'])) { $event_name = $_GET['to_worker_id']; $to_connection_id = $_GET['to_connection_id']; $content = $_GET['content']; Channel\Client::publish($event_name, array( 'to_connection_id' => $to_connection_id, 'content' => $content )); } // 是全域性廣播資料 else { $event_name = '廣播'; $content = $_GET['content']; Channel\Client::publish($event_name, array( 'content' => $content )); } }; Worker::runAll();

測試 (假設都是本機127.0.0.1執行)

1、執行服務端

 php start.php start
Workerman[start.php] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.2.7          PHP version:5.4.37
------------------------ WORKERS -------------------------------
user          worker         listen                    processes status
root          ChannelServer  text://0.0.0.0:2206        1         [OK]
root          pusher         websocket://0.0.0.0:4236   2         [OK]
root          publisher      http://0.0.0.0:4237        1         [OK]
----------------------------------------------------------------
Press Ctrl-C to quit. Start success.

2、客戶端連線服務端

開啟chrome瀏覽器,按F12開啟除錯控制檯,在Console一欄輸入(或者把下面程式碼放入到html頁面用js執行)

// 假設服務端ip為127.0.0.1,測試時請改成實際服務端ip
ws = new WebSocket("ws://127.0.0.1:4236");
ws.onmessage = function(e) {
    alert("收到服務端的訊息:" + e.data);
};

3、通過呼叫http介面推送

url訪問 http://127.0.0.1:4237/?content={$content} 向所有客戶端連線推送$content資料

url訪問http://127.0.0.1:4237/?to_worker_id={$worker_id}&to_connection_id={$connection_id}&content={$content}向某個worker程序中的某個客戶端連線推送$content資料

注意:測試時把127.0.0.1 {$worker_id} {$connection_id}{$content} 換成實際值