
在今天的信息時代,在線投票系統(tǒng)成為了選舉、調(diào)查等活動中必不可少的一部分。與傳統(tǒng)的投票方式相比,在線投票系統(tǒng)不僅便于操作,而且速度快,可以實現(xiàn)實時統(tǒng)計數(shù)據(jù)等功能。
本文將介紹如何使用 PHP 的 Workerman 框架搭建一個基于 WebSocket 協(xié)議的在線投票系統(tǒng)。同時會給出具體的代碼示例,供讀者參考。
一、什么是 Workerman?
Workerman 是一款高性能、開源的 PHP 異步框架,它基于事件驅(qū)動思想,可以輕松地實現(xiàn)長連接應(yīng)用,如 WebSocket、即時通訊等應(yīng)用。
Workerman 支持 TCP、UDP 和 HTTP 等協(xié)議,具有高并發(fā)、低內(nèi)存消耗等特點。相較于傳統(tǒng)的 Web 應(yīng)用,Workerman 具有更強(qiáng)的實時性和穩(wěn)定性,因此適用于在線游戲、聊天室、彈幕、消息推送等應(yīng)用場景。
二、搭建 WebSocket 服務(wù)器
在開始之前,我們需要確保已經(jīng)安裝了 PHP 環(huán)境,并且安裝了 Workerman 框架。具體的安裝流程可以參考官方文檔。
接下來,我們需要新建一個 PHP 文件,用于啟動 WebSocket 服務(wù)器,并且監(jiān)聽客戶端發(fā)送的消息。假設(shè)我們在本地 127.0.0.1
的 8080
端口開啟 WebSocket 服務(wù),代碼如下:127.0.0.1
的 8080
端口開啟 WebSocket 服務(wù),代碼如下:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use WorkermanWorker;
use WorkermanWebServer;
use WorkermanProtocolsWebsocket;
$ws_worker = new Worker('websocket://127.0.0.1:8080');
$ws_worker->count = 1;
$ws_worker->onWorkerStart = function() {
echo "WebSocket server started
";
};
$ws_worker->onConnect = function($connection) {
echo "New connection established: {$connection->id}
";
};
$ws_worker->onMessage = function($connection, $data) {
echo "Received a message from {$connection->id}: $data
";
};
Worker::runAll();
以上代碼中,我們使用 Workerman 的 Worker
類來開啟一個 WebSocket 服務(wù)器,并監(jiān)聽 127.0.0.1
的 8080
端口。count
屬性指定了開啟的進(jìn)程數(shù)。當(dāng)有客戶端連接時,onConnect
回調(diào)函數(shù)將會被觸發(fā);當(dāng)有客戶端發(fā)送消息時,onMessage
回調(diào)函數(shù)將被觸發(fā)。我們可以在這兩個回調(diào)函數(shù)中處理客戶端的連接和消息。
三、實現(xiàn)在線投票系統(tǒng)
在投票系統(tǒng)中,我們需要支持多個用戶同時進(jìn)行投票,并且需要實時地顯示投票結(jié)果。為了實現(xiàn)這樣的功能,我們需要使用 PHP 的共享內(nèi)存機(jī)制,以及在客戶端和服務(wù)器之間傳遞數(shù)據(jù)的 JSON 格式。
首先,我們需要在服務(wù)器端定義一個關(guān)聯(lián)數(shù)組 $votes
,用于存儲每個投票選項的得票數(shù)。在每次接收到客戶端的投票請求時,我們會將對應(yīng)的選項得票數(shù)加一,而不同選項的得票數(shù)則保存在不同的數(shù)組元素中。
<?php
// ...
$votes = [
'Option 1' => 0,
'Option 2' => 0,
'Option 3' => 0,
];
$ws_worker->onMessage = function($connection, $data) use ($votes) {
$data = json_decode($data, true);
if (!isset($data['option']) || !isset($votes[$data['option']])) {
// 投票選項不存在或者為空
$connection->send(json_encode([
'code' => 400,
'message' => 'Invalid option'
]));
return;
}
$votes[$data['option']]++;
// 廣播投票結(jié)果
broadcast(json_encode([
'code' => 200,
'message' => 'Vote successfully',
'data' => $votes
]));
};
function broadcast($data) {
global $ws_worker;
foreach ($ws_worker->connections as $connection) {
$connection->send($data);
}
}
以上代碼中,我們使用了 PHP 的 global
關(guān)鍵字,將 $ws_worker
對象引入到 broadcast
函數(shù)中,在每次投票后將投票結(jié)果以 JSON 格式廣播給所有連接的客戶端。在上面的代碼中,我們還定義了一個 broadcast
函數(shù),用于將消息發(fā)送給所有已連接的客戶端。
接下來,我們需要實現(xiàn)客戶端的投票功能。在 HTML 頁面中,我們可以通過 JavaScript 代碼創(chuàng)建 WebSocket 對象,用于與服務(wù)器進(jìn)行實時通信。
<!DOCTYPE html>
<html>
<head>
<title>WebSocket - Online Voting System</title>
</head>
<body>
<h1>Online Voting System</h1>
<p>Vote for your favorite option:</p>
<form id="form">
<input type="radio" name="option" value="Option 1">Option 1<br>
<input type="radio" name="option" value="Option 2">Option 2<br>
<input type="radio" name="option" value="Option 3">Option 3<br>
<input type="submit" value="Vote">
</form>
<ul id="result">
<li>Option 1: <span id="vote1"></span></li>
<li>Option 2: <span id="vote2"></span></li>
<li>Option 3: <span id="vote3"></span></li>
</ul>
<script type="text/javascript">
var ws = new WebSocket('ws://127.0.0.1:8080');
ws.onopen = function() {
console.log('WebSocket connected');
}
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
if (data.code === 200) {
// 投票成功
updateVotes(data.data);
} else {
// 投票失敗
console.error(data.message);
}
}
function updateVotes(votes) {
document.querySelector('#vote1').innerHTML = votes['Option 1'];
document.querySelector('#vote2').innerHTML = votes['Option 2'];
document.querySelector('#vote3').innerHTML = votes['Option 3'];
}
var form = document.querySelector('#form');
form.addEventListener('submit', function(event) {
event.preventDefault();
var option = document.querySelector('input[name="option"]:checked');
if (!option) {
console.error('Please choose an option');
return;
}
var data = {
option: option.value
};
ws.send(JSON.stringify(data));
option.checked = false;
});
</script>
</body>
</html>
以上代碼中,我們使用了 WebSocket
對象的 onopen
、onmessage
兩個回調(diào)函數(shù),分別用于在連接建立后輸出日志和接收來自服務(wù)器的消息。在表單中,我們使用 submit
事件來捕獲用戶投票的行為,并通過 WebSocket
對象將投票信息發(fā)送到服務(wù)器。在每次接收到服務(wù)器發(fā)送的投票結(jié)果時,我們會通過 updateVotes
rrreee
以上代碼中,我們使用 Workerman 的
Worker
類來開啟一個 WebSocket 服務(wù)器,并監(jiān)聽
127.0.0.1
的
8080
端口。
count
屬性指定了開啟的進(jìn)程數(shù)。當(dāng)有客戶端連接時,
onConnect
回調(diào)函數(shù)將會被觸發(fā);當(dāng)有客戶端發(fā)送消息時,
onMessage
回調(diào)函數(shù)將被觸發(fā)。我們可以在這兩個回調(diào)函數(shù)中處理客戶端的連接和消息。
三、實現(xiàn)在線投票系統(tǒng)
在投票系統(tǒng)中,我們需要支持多個用戶同時進(jìn)行投票,并且需要實時地顯示投票結(jié)果。為了實現(xiàn)這樣的功能,我們需要使用 PHP 的共享內(nèi)存機(jī)制,以及在客戶端和服務(wù)器之間傳遞數(shù)據(jù)的 JSON 格式。????首先,我們需要在服務(wù)器端定義一個關(guān)聯(lián)數(shù)組
$votes
,用于存儲每個投票選項的得票數(shù)。在每次接收到客戶端的投票請求時,我們會將對應(yīng)的選項得票數(shù)加一,而不同選項的得票數(shù)則保存在不同的數(shù)組元素中。??rrreee??以上代碼中,我們使用了 PHP 的
global
關(guān)鍵字,將
$ws_worker
對象引入到
broadcast
函數(shù)中,在每次投票后將投票結(jié)果以 JSON 格式廣播給所有連接的客戶端。在上面的代碼中,我們還定義了一個
broadcast
函數(shù),用于將消息發(fā)送給所有已連接的客戶端。????接下來,我們需要實現(xiàn)客戶端的投票功能。在 HTML 頁面中,我們可以通過 JavaScript 代碼創(chuàng)建 WebSocket 對象,用于與服務(wù)器進(jìn)行實時通信。??rrreee??以上代碼中,我們使用了
WebSocket
對象的
onopen
、
onmessage
兩個回調(diào)函數(shù),分別用于在連接建立后輸出日志和接收來自服務(wù)器的消息。在表單中,我們使用
submit
事件來捕獲用戶投票的行為,并通過
WebSocket
對象將投票信息發(fā)送到服務(wù)器。在每次接收到服務(wù)器發(fā)送的投票結(jié)果時,我們會通過
updateVotes
函數(shù)更新 HTML 頁面中的投票數(shù)據(jù)。????四、總結(jié)????本文介紹了如何使用 PHP 的 Workerman 框架實現(xiàn)一個基于 WebSocket 協(xié)議的在線投票系統(tǒng),并且給出了具體的代碼示例。通過本文的學(xué)習(xí),讀者應(yīng)該對 Workerman 框架、共享內(nèi)存機(jī)制、WebSocket 協(xié)議等知識有了更深入的了解和掌握。??
以上是Workerman開發(fā):如何實現(xiàn)基于WebSocket協(xié)議的在線投票系統(tǒng)的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!