WebSocket 是什麼? ReactPHP 怎麼用? 只要5步驟用 PHP 實作 WebSocket 聊天室

Ratchet 是一款基於 PHP 的 WebSocket 框架,專為即時應用程式設計。它的輕量特性和易用性,使其成為 PHP 開發者實現 WebSocket 功能的理想選擇。如果你正在尋找如何提升 WebSocket 效能並充分利用 Ratchet,本篇文章將為你提供全面的解答。


WebSocket 是什麼?

WebSocket 是一種雙向通訊協議,允許伺服器與用戶端之間進行持續的訊息交換。它與 HTTP 的最大不同是 WebSocket 只需建立一次連接,之後雙方就可以持續通信,而不需要反覆進行 HTTP 的請求和回應。這使得 WebSocket 非常適合即時性需求高的應用,例如:

  • 即時通訊:像 Slack 或 Discord 這樣的聊天應用。
  • 即時數據更新:股市交易平台或運動比賽的即時比分。
  • 多人遊戲:例如 Web 上的象棋遊戲或多人射擊遊戲。

假設你正在開發一個即時聊天室應用,每個用戶都會收到來自其他用戶的訊息更新。透過 WebSocket,所有訊息可以在毫秒內抵達,而不像 HTTP 需要頻繁發起請求。


Ratchet什麼?

Ratchet 是一個基於 PHP 的 WebSocket 框架,讓開發者可以快速建立即時的雙向通訊應用。不同於傳統的 HTTP 請求-回應模式,Ratchet 支援長時間連接,適用於聊天應用、即時遊戲、多用戶協作工具等場景。


為什麼選擇 Ratchet 實現 WebSocket?

  1. 易於使用:Ratchet 提供了詳細的文檔和範例,幫助開發者快速解決問題,提升開發效率,即使是初學者也可以快速上手
  2. 輕量框架:Ratchet 專注於 WebSocket 功能,避免了許多不必要的特性,使其成為一個輕量級的選擇。這不僅減少了學習成本,也提高了應用的性能。
  3. 卓越的性能:Ratchet 是建立在 ReactPHP 之上的,這意味著它具備非阻塞 I/O 的優勢,可以處理大量的並發連接,適合高流量的應用場景。
  4. 活躍的開發社群:Ratchet 擁有一個活躍的社群,Github上有6K的星星,開發者可以在論壇和社交媒體上尋求幫助,分享經驗,這對於解決問題和獲取新知識非常有幫助。

WebSocket 效能優化的基本原則

在使用 Ratchet 建立 WebSocket 伺服器時,以下幾點是提升效能的核心原則:

  1. 控制連接數:避免單一伺服器處理過多請求。
  2. 壓縮資料:減少傳輸的資料大小。
  3. 事件循環優化:使用更高效的事件循環機制(如 ExtEventLoop)。

聊天室實現步驟

1. 安裝 Ratchet

首先,你需要安裝 Ratchet。可以使用 Composer 來安裝:

composer require cboden/ratchet

2. 建立 WebSocket 伺服器

創建一個 PHP 檔案(例如 chat-server.php),並添加以下程式:

<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

require 'vendor/autoload.php';

class Chat implements MessageComponentInterface {
protected $clients;

public function __construct() {
$this->clients = new \SplObjectStorage;
}

public function onOpen(ConnectionInterface $conn) {
// 限制最大連接數
$maxConnections = 100; // 設定最大連接數
if (count($this->clients) >= $maxConnections) {
$conn->close(); // 超出限制,拒絕連接
echo "Connection rejected: max connections reached ({$maxConnections})\n";
return;
}
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}

public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
// 廣播消息給所有連接的客戶端
if ($from !== $client) {
$client->send($msg);
}
}
}

public function onClose(ConnectionInterface $conn) {
// 移除斷開的連接
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}

public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}

$chatApp = new Chat();
// 使用 ExtEventLoop 代替 StreamSelectLoop
$loop = new ExtEventLoop();
$server = IoServer::factory(
new HttpServer(
new WsServer(
$chatApp
)
),
8003,
'0.0.0.0',
$loop
);

// 使用定期計時器來清理不活動的連接
$loop->addPeriodicTimer(5, function() use ($chatApp) {
foreach ($chatApp->clients as $client) {
if (!$client->isConnected()) {
$chatApp->clients->detach($client);
}
}
echo "Cleanup inactive connections";
});

$server->run();

3. 啟動伺服器

在命令行中運行以下命令來啟動伺服器:

php chat-server.php

4. 建立前端界面

你需要一個簡單的 HTML 界面來與 WebSocket 伺服器進行交互。創建一個 index.html 檔案,並添加以下程式:

<!DOCTYPE html>
<html>
<head>
<title>聊天室</title>
<style>
#messages { border: 1px solid #ccc; height: 300px; overflow-y: scroll; }
</style>
</head>
<body>
<div id="messages"></div>
<input id="message" type="text" placeholder="輸入消息..." />
<button onclick="sendMessage()">發送</button>

<script>
const conn = new WebSocket('ws://localhost:8080');

// 在前端解壓縮消息
conn.onmessage = function(e) {
const messages = document.getElementById('messages');
const decodedData = pako.inflate(e.data, { to: 'string' }); // 使用 pako.js 解壓縮
messages.innerHTML += '<div>' + decodedData + '</div>';
messages.scrollTop = messages.scrollHeight;
};

function sendMessage() {
const messageInput = document.getElementById('message');
conn.send(messageInput.value);
messageInput.value = '';
}
</script>
</body>
</html>

使用 pako.js 處理解壓縮。

5. 測試聊天室

在瀏覽器中打開 index.html,然後你可以在多個窗口中打開它們,開始即時聊天。

總結

使用 Ratchet 建立即時聊天室非常簡單。透過以上步驟,你可以快速搭建一個基本的聊天室應用。隨著需求的增長,你可以進一步擴展功能,例如用戶身份驗證、消息存儲等。希望這篇文章能幫助你開始使用 Ratchet 進行 WebSocket 開發!





主頁 » PHP » WebSocket 是什麼? ReactPHP 怎麼用? 只要5步驟用 PHP 實作 WebSocket 聊天室




2 Comments

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *