php实现websoc
PHP 实现 WebSocket
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,常用于实时应用程序。PHP 可以通过以下方法实现 WebSocket 功能。
使用 Ratchet 库
Ratchet 是一个流行的 PHP WebSocket 库,基于 ReactPHP 实现,适合构建实时应用。
安装 Ratchet:
composer require cboden/ratchet
创建 WebSocket 服务器:
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
class Chat implements \Ratchet\MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(\Ratchet\ConnectionInterface $conn) {
$this->clients->attach($conn);
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(\Ratchet\ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($from !== $client) {
$client->send($msg);
}
}
}
public function onClose(\Ratchet\ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection closed: {$conn->resourceId}\n";
}
public function onError(\Ratchet\ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
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
手动实现 WebSocket 握手
如果不想依赖第三方库,可以手动实现 WebSocket 握手协议。
示例代码:
<?php
$host = '0.0.0.0';
$port = 8080;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socket, $host, $port);
socket_listen($socket);
$clients = [$socket];
while (true) {
$read = $clients;
$write = $except = null;
socket_select($read, $write, $except, 0);
if (in_array($socket, $read)) {
$newClient = socket_accept($socket);
$header = socket_read($newClient, 1024);
if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $header, $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($newClient, $response, strlen($response));
$clients[] = $newClient;
}
$key = array_search($socket, $read);
unset($read[$key]);
}
foreach ($read as $client) {
$data = socket_read($client, 1024);
if ($data === false) {
$key = array_search($client, $clients);
unset($clients[$key]);
continue;
}
foreach ($clients as $sendClient) {
if ($sendClient != $socket && $sendClient != $client) {
socket_write($sendClient, $data, strlen($data));
}
}
}
}
socket_close($socket);
WebSocket 客户端连接
使用 JavaScript 连接 WebSocket 服务器:
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => {
console.log('Connected');
socket.send('Hello Server');
};
socket.onmessage = (event) => {
console.log('Message from server:', event.data);
};
注意事项
-
WebSocket 服务器需要长期运行,建议使用 Supervisor 或 systemd 管理进程。
-
生产环境建议使用 Nginx 反向代理 WebSocket,配置如下:
location /ws { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } -
对于高并发场景,Swoole 性能优于 Ratchet,但需要安装扩展。
-
手动实现 WebSocket 仅适合学习,生产环境建议使用成熟库。







