php 实现websocket
PHP 实现 WebSocket 的方法
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。PHP 可以通过以下方式实现 WebSocket 功能。
使用 Ratchet 库
Ratchet 是一个流行的 PHP WebSocket 库,基于 ReactPHP 实现。以下是使用 Ratchet 实现 WebSocket 服务器的步骤。
安装 Ratchet:
composer require cboden/ratchet
创建 WebSocket 服务器:
<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
class MyWebSocket implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($client !== $from) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection closed: {$conn->resourceId}\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
$server = IoServer::factory(
new HttpServer(
new WsServer(
new MyWebSocket()
)
),
8080
);
$server->run();
运行服务器:
php server.php
使用 Swoole 扩展
Swoole 是一个高性能的 PHP 协程框架,内置 WebSocket 支持。
安装 Swoole:
pecl install swoole
创建 WebSocket 服务器:
<?php
$server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
echo "Connection open: {$request->fd}\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
foreach ($server->connections as $fd) {
if ($fd !== $frame->fd) {
$server->push($fd, $frame->data);
}
}
});
$server->on('close', function ($server, $fd) {
echo "Connection closed: {$fd}\n";
});
$server->start();
运行服务器:
php server.php
原生 PHP 实现
如果需要更底层的实现,可以使用 PHP 原生 Socket 函数。
创建 WebSocket 握手和处理逻辑:
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
while (true) {
$client = socket_accept($socket);
$headers = socket_read($client, 1024);
if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $matches)) {
$key = base64_encode(sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
$response = "HTTP/1.1 101 Switching Protocols\r\n";
$response .= "Upgrade: websocket\r\n";
$response .= "Connection: Upgrade\r\n";
$response .= "Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($client, $response, strlen($response));
}
// 处理 WebSocket 消息
$data = socket_read($client, 1024);
// 解码和编码逻辑...
}
socket_close($socket);
客户端连接示例
使用 JavaScript 连接 WebSocket 服务器:
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => console.log('Connected');
socket.onmessage = (e) => console.log('Message:', e.data);
socket.send('Hello WebSocket');
注意事项
- Ratchet 和 Swoole 是更推荐的方式,原生实现复杂度较高。
- 生产环境建议使用 Swoole 以获得更好的性能。
- 确保防火墙允许 WebSocket 使用的端口(如 8080、9501)。







