PHP Websocket開發教程,建立即時問卷調查功能,需要具體程式碼範例
Websocket技術是一種新興的網路協議,它可以在web 應用中構建即時通訊功能。和傳統的 HTTP 協定不同,Websocket 協定可以實現雙向通信,並且能夠不間斷的發送和接收資料。在本文中,我們將介紹如何使用 PHP 和 Websocket 技術建立即時問卷調查功能,並提供具體的程式碼範例。
Ratchet 是一個 PHP 函式庫,用於開發 Websocket 應用程式。在開始之前,你需要在伺服器上安裝 Ratchet 。使用以下命令:
composer require cboden/ratchet
#首先,我們需要建立一個 Ratchet 的 WebSocket 伺服器。在本範例中,我們將把所有程式碼放在一個 PHP 檔案中。在此文件中,我們將建立一個類,該類將擴展 RatchetWebSocketWsServer 類。在建構函式中,我們將初始化一個實例變數 $clients
,該變數將儲存已連接的客戶端。
以下是伺服器程式碼:
<?php require __DIR__ . '/vendor/autoload.php'; // 引入 ratchet use RatchetMessageComponentInterface; use RatchetConnectionInterface; use RatchetWebSocketWsServer; class PollServer implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo 'Client ' . $conn->resourceId . ' connected '; } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo 'Client ' . $conn->resourceId . ' disconnected '; } public function onMessage(ConnectionInterface $from, $msg) { echo 'Received message ' . $msg . ' from client ' . $from->resourceId . " "; // 在这里处理逻辑... } public function onError(ConnectionInterface $conn, Exception $e) { echo "An error has occurred: {$e->getMessage()} "; $conn->close(); } } $server = new RatchetApp('localhost', 8080); // 创建一个新的 WebSocket 服务器 $server->route('/poll', new WsServer(new PollServer())); // 定义路由 $server->run(); // 启动服务器
上述程式碼定義了一個名為 PollServer
的類,該類別實作了 RatchetMessageComponentInterface
介面。 MessageComponentInterface
介面非常簡單,它只有四個方法,分別是onOpen
、onClose
、onMessage
和onError
。這些方法會在客戶端連接到伺服器時、從伺服器斷開連線時、接收到新訊息時和遇到錯誤時呼叫。在上面的程式碼中,我們只是簡單地輸出了一些日誌,但在處理實際邏輯時,你可以根據需要進行更改。
接下來,我們需要將 PollServer
類別傳遞給 RatchetWebSocketWsServer
類別的建構子中。這將建立一個新的 WebSocket 伺服器,該伺服器將使用 WebSocket 協定與客戶端進行通訊。
最後,我們需要定義一個路由,以便客戶端可以連接到伺服器。在上面的程式碼中,我們定義了一個名為 /poll
的路由。在生產環境中,你應該為 WebSocket 伺服器使用真實的網域名稱和連接埠。
在本範例中,我們將使用 JavaScript 編寫客戶端程式碼。首先,在HTML 檔案中新增以下程式碼來建立一個WebSocket 連線:
<!DOCTYPE html> <html> <head> <title>Real-time Poll</title> </head> <body> <h1>Real-time Poll</h1> <script> const connection = new WebSocket('ws://localhost:8080/poll'); // 替换为真实的域名和端口 connection.addEventListener('open', () => { console.log('Connected'); }); connection.addEventListener('message', event => { const message = JSON.parse(event.data); console.log('Received', message); }); connection.addEventListener('close', () => { console.log('Disconnected'); }); connection.addEventListener('error', error => { console.error(error); }); </script> </body> </html>
上面的程式碼建立了一個名為connection
的新WebSocket 對象,並使用ws:/ /localhost:8080/poll
作為伺服器URL。在生產環境中,你應該將此 URL 替換為真實的伺服器網域和連接埠。
接下來,我們新增了幾個事件偵聽器,用於處理連線建立、接收訊息、連線中斷和錯誤事件。在接收到訊息時,我們使用 JSON.parse
將訊息解析為 JavaScript 對象,並在控制台上記錄。
現在我們已經建立了 WebSocket 伺服器和用戶端,我們需要實作即時問卷調查功能。考慮以下程式碼範例:
public function onMessage(ConnectionInterface $from, $msg) { echo 'Received message ' . $msg . ' from client ' . $from->resourceId . " "; $data = json_decode($msg, true); switch ($data['action']) { case 'vote': $vote = $data['vote']; $this->broadcast([ 'action' => 'update', 'votes' => [ 'yes' => $this->getVoteCount('yes'), 'no' => $this->getVoteCount('no') ] ]); break; } } private function broadcast($message) { foreach ($this->clients as $client) { $client->send(json_encode($message)); } } private function getVoteCount($option) { // 在这里查询投票选项的数量... }
在上面的程式碼中,我們在 onMessage
方法中處理客戶端發送的訊息。此方法對訊息進行解碼,並使用 switch
語句檢查 action
欄位。如果 action
等於 vote
,則我們將更新投票計數並使用 broadcast
方法向所有用戶端發送更新結果。
在 broadcast
方法中,我們使用一個循環遍歷所有客戶端並將訊息傳送到每個客戶端。此方法將 JSON 編碼的訊息傳送到客戶端,用戶端將與 connection.addEventListener('message', ...)
事件處理程序中註冊的事件處理程序配合使用。
以下是本文中所有程式碼範例的完整版本:
server.php:##
<?php require __DIR__ . '/vendor/autoload.php'; use RatchetMessageComponentInterface; use RatchetConnectionInterface; use RatchetWebSocketWsServer; class PollServer implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo 'Client ' . $conn->resourceId . ' connected '; } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo 'Client ' . $conn->resourceId . ' disconnected '; } public function onMessage(ConnectionInterface $from, $msg) { echo 'Received message ' . $msg . ' from client ' . $from->resourceId . " "; $data = json_decode($msg, true); switch ($data['action']) { case 'vote': $vote = $data['vote']; $this->broadcast([ 'action' => 'update', 'votes' => [ 'yes' => $this->getVoteCount('yes'), 'no' => $this->getVoteCount('no') ] ]); break; } } public function onError(ConnectionInterface $conn, Exception $e) { echo "An error has occurred: {$e->getMessage()} "; $conn->close(); } private function broadcast($message) { foreach ($this->clients as $client) { $client->send(json_encode($message)); } } private function getVoteCount($option) { // 在这里查询投票选项的数量... } } $server = new RatchetApp('localhost', 8080); $server->route('/poll', new WsServer(new PollServer())); $server->run();index .html:
<!DOCTYPE html> <html> <head> <title>Real-time Poll</title> </head> <body> <h1>Real-time Poll</h1> <form> <label><input type="radio" name="vote" value="yes"> Yes</label> <label><input type="radio" name="vote" value="no"> No</label> <button type="submit">Vote</button> </form> <ul> <li>Yes: <span id="yes-votes">0</span></li> <li>No: <span id="no-votes">0</span></li> </ul> <script> const connection = new WebSocket('ws://localhost:8080/poll'); connection.addEventListener('open', () => { console.log('Connected'); }); connection.addEventListener('message', event => { const message = JSON.parse(event.data); if (message.action === 'update') { document.getElementById('yes-votes').textContent = message.votes.yes; document.getElementById('no-votes').textContent = message.votes.no; } }); connection.addEventListener('close', () => { console.log('Disconnected'); }); connection.addEventListener('error', error => { console.error(error); }); document.querySelector('form').addEventListener('submit', event => { event.preventDefault(); const vote = document.querySelector('input[name="vote"]:checked').value; connection.send(JSON.stringify({ action: 'vote', vote: vote })); }); </script> </body> </html>在上述程式碼範例中,我們提供了一個簡單的HTML 表單,用於向伺服器發送投票結果。當使用者提交表單時,我們將投票結果作為 JSON 物件傳送到伺服器上的 WebSocket 連線。 在客戶端收到更新訊息時,我們在 HTML 中更新投票結果。
以上是PHP Websocket開發教程,建立即時問卷調查功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!