WebSockets 通过单个 TCP 连接提供全双工通信通道。对于聊天应用程序、实时通知和协作工具等实时通信应用程序来说,它们非常方便。本文将探讨如何在 PHP 中实现 WebSockets。
为什么要使用 WebSockets?
传统的 HTTP 是一种请求-响应协议,对于实时应用程序来说效率不高,因为客户端必须反复轮询服务器以检查更新。另一方面,WebSockets 建立了一个持久连接,允许数据双向流动,而无需多个 HTTP 请求的开销。
使用 Ratchet 设置 WebSocket 服务器
要在 PHP 中设置 WebSocket 服务器,我们将使用 Ratchet 库,它是处理 WebSocket 连接的常用 PHP 库。下面介绍如何开始:
前提条件
- PHP 7.0 或更高版本
- Composer – PHP 依赖关系管理工具
步骤 1:安装 Ratchet
首先,我们需要使用 Composer 安装 Ratchet。如果没有安装 Composer,可以从 getcomposer.org 下载。
composer require cboden/ratchet
步骤 2:创建 WebSocket 服务器
新建一个名为 server.php 的 PHP 文件,并添加以下代码:
<?php
require 'vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$numRecv = count($this->clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->clients as $client) {
if ($from !== $client) {
// Send the message to all clients except the sender
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
// The connection is closed, remove it from the clients list
$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();
}
}
// Run the server
$server = \Ratchet\App::factory(function () {
$loop = React\EventLoop\Factory::create();
$pusher = new Chat();
// Listen for the 'Chat' application on port 8080
$webSock = new React\Socket\Server('0.0.0.0:8080', $loop);
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
$pusher
)
),
$webSock
);
$loop->run();
}, 8080, '0.0.0.0');
echo "WebSocket server running at ws://localhost:8080\n";
步骤 3:运行 WebSocket 服务器
使用 PHP CLI 运行 WebSocket 服务器:
php server.php
该命令将启动 WebSocket 服务器,监听 ws://localhost:8080 上的连接。
步骤 4:创建 WebSocket 客户端
要与 WebSocket 服务器交互,我们需要一个客户端。创建一个名为 client.html 的 HTML 文件,并添加以下代码:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client</title>
</head>
<body>
<h1>WebSocket Client</h1>
<input type="text" id="message" placeholder="Type a message..." />
<button onclick="sendMessage()">Send</button>
<ul id="messages"></ul>
<script>
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
var messages = document.getElementById('messages');
var message = document.createElement('li');
message.textContent = e.data;
messages.appendChild(message);
};
function sendMessage() {
var input = document.getElementById('message');
var msg = input.value;
conn.send(msg);
input.value = '';
}
</script>
</body>
</html>
步骤 5:测试 WebSocket 连接
- 在 Web 浏览器中打开 client.html 文件。
- 打开开发者控制台查看连接日志。
- 输入一条信息,然后点击 “发送”。
如果打开多个浏览器窗口,信息会出现在所有窗口中,这表明 WebSockets 实现了实时通信。
使用 Swoole 设置 WebSocket 服务器
前提条件
- PHP 7.2 或更高版本
- Swoole PHP 扩展
安装 Swoole
如果尚未安装 Swoole,可使用以下命令进行安装:
pecl install swoole
确保在 php.ini
文件中启用了 Swoole 扩展:
extension=swoole
步骤 1:使用 Swoole 创建 WebSocket 服务器
创建名为 swoole_server.php
的 PHP 文件并添加以下代码:
<?php
use Swoole\WebSocket\Server;
$server = new Server("0.0.0.0", 9502);
$server->on('open', function (Server $server, $request) {
echo "Connection opened: {$request->fd}\n";
});
$server->on('message', function (Server $server, $frame) {
echo "Received message: {$frame->data}\n";
foreach ($server->connections as $fd) {
$server->push($fd, $frame->data);
}
});
$server->on('close', function ($server, $fd) {
echo "Connection closed: {$fd}\n";
});
$server->start();
步骤 2:运行 WebSocket 服务器
使用 PHP CLI 运行 WebSocket 服务器:
php swoole_server.php
该命令将启动 WebSocket 服务器,监听 ws://localhost:9502 上的连接。
步骤 3:创建 WebSocket 客户端
要与 WebSocket 服务器交互,请创建一个名为 client.html 的 HTML 文件并添加以下代码:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client</title>
</head>
<body>
<h1>WebSocket Client</h1>
<input type="text" id="message" placeholder="Type a message..." />
<button onclick="sendMessage()">Send</button>
<ul id="messages"></ul>
<script>
var conn = new WebSocket('ws://localhost:9502');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
var messages = document.getElementById('messages');
var message = document.createElement('li');
message.textContent = e.data;
messages.appendChild(message);
};
function sendMessage() {
var input = document.getElementById('message');
var msg = input.value;
conn.send(msg);
input.value = '';
}
</script>
</body>
</html>
步骤 4:测试 WebSocket 连接
- 在Web浏览器中打开 client.html 文件。
- 打开开发者控制台查看连接日志。
- 在输入框中键入一条信息,然后点击 “发送”。
如果打开多个浏览器窗口,信息会出现在所有窗口中,这表明 WebSockets 实现了实时通信。
确保 WebSockets 连接的安全
要确保 PHP 中 WebSocket 连接的安全,请按以下步骤操作:
- 使用 wss:// 而不是 ws://:在建立 WebSocket 连接时,使用 wss:// 协议而不是 ws://。这将通过加密数据为通信增加一个安全层。
- 使用 Nginx 进行反向代理:使用 Nginx 等服务器建立反向代理来处理 WebSocket 连接,并在 WebSocket 连接上启用 SSL 以确保通信安全。
服务器端安全检查:
- 在服务器端实施安全检查(客户端检查是为了用户体验,而非安全性)。
- 确保无法猜测会话 ID。
- 清理不再使用的会话。
- 如果符合您的使用情况,考虑强制执行每个用户一个会话和每个会话一个 WebSocket 连接。
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。