php – Workerman – 使用 Websocket 廣播給所有客戶端
預設只推送給 connect 單一 client 端,那如果要推送給所有人呢?可以藉由搭配訂閱的功能。
除了透過 composer 安裝 workerman 之外,還需要安裝 Channel分佈式通訊組件: workerman/channel
1 2 3 4 |
composer require workerman/workerman composer require workerman/channel |
接著貼上 start.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php require_once __DIR__ . '/vendor/autoload.php'; use Workerman\Worker; use Channel\Client; use Channel\Server; // 初始化一个Channel服务端 $channel_server = new Server('0.0.0.0', 2206); // Create a Websocket server $ws_worker = new Worker("websocket://0.0.0.0:2346"); // 4 processes $ws_worker->count = 4; $ws_worker->onWorkerStart = function ($worker) { // Channel客户端连接到Channel服务端 Client::connect('0.0.0.0', 2206); // 订阅broadcast事件,并注册事件回调 Client::on('broadcast', function ($event_data) use ($worker) { // 向当前worker进程的所有客户端广播消息 foreach ($worker->connections as $connection) { $connection->send($event_data); } }); }; // Emitted when data received $ws_worker->onMessage = function ($connection, $data) use ($ws_worker) { // 向所有worker进程发布broadcast事件 Channel\Client::publish('broadcast', $data); }; // Emitted when connection closed $ws_worker->onClose = function ($connection) { echo "Connection closed\n"; }; // Run worker Worker::runAll(); |
接著啟動服務,我們透過 php 運行
1 2 3 |
php start.php |
建立 Client 端部分
1 2 3 4 |
<input type="text" class="name" placeholder="請輸入姓名" autofocus> <input type="submit" value="發送" onclick="send_msg(); "> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var wsServer = 'ws://0.0.0.0:2346'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("成功連接到 WebSocket 服務"); }; websocket.onclose = function (evt) { console.log("關閉連接 WebSocket 服務"); }; websocket.onmessage = function (evt) { console.log('伺服器顯示:' + evt.data); }; websocket.onerror = function (evt, e) { console.log('發生錯誤: ' + evt.data); }; // 發送訊息給所有人 const send_msg = function (){ var name = document.getElementsByClassName('name')[0].value; var msg = JSON.stringify({ message: '你好,我是' + name, }) websocket.send(msg) } |