PHP WebSocket
外观
PHP WebSocket[编辑 | 编辑源代码]
WebSocket 是一种在单个TCP连接上进行全双工通信的协议,允许服务器和客户端之间实时交换数据。在PHP中,WebSocket通常用于构建实时应用程序,如聊天系统、在线游戏或股票行情推送等。
简介[编辑 | 编辑源代码]
传统的HTTP协议是无状态的,每次请求都需要建立新的连接。而WebSocket通过一次握手建立持久连接,实现低延迟的双向通信。PHP可以通过扩展库(如Ratchet或Swoole)实现WebSocket服务器。
核心特点[编辑 | 编辑源代码]
- 全双工通信:客户端和服务器可以同时发送和接收数据。
- 低延迟:避免HTTP的重复握手开销。
- 轻量级:数据帧头仅2-10字节。
工作原理[编辑 | 编辑源代码]
WebSocket通信分为两个阶段: 1. 握手阶段:客户端通过HTTP Upgrade头请求切换到WebSocket协议。 2. 数据传输阶段:通过帧(Frame)格式交换数据。
PHP实现方式[编辑 | 编辑源代码]
使用Ratchet库[编辑 | 编辑源代码]
Ratchet是PHP的WebSocket库,基于ReactPHP事件循环。
// 安装Ratchet: composer require cboden/ratchet
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
class MyChat 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 {$conn->resourceId} disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
$server = IoServer::factory(
new HttpServer(new WsServer(new MyChat())),
8080
);
$server->run();
输出示例:
New connection! (1) New connection! (2) Connection 1 disconnected
使用Swoole扩展[编辑 | 编辑源代码]
Swoole提供了更高性能的WebSocket实现:
$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 ($server, $frame) {
foreach ($server->connections as $fd) {
if ($fd != $frame->fd) {
$server->push($fd, $frame->data);
}
}
});
$server->on('close', function ($server, $fd) {
echo "connection close: {$fd}\n";
});
$server->start();
握手过程详解[编辑 | 编辑源代码]
WebSocket握手使用HTTP头交换密钥:
实际应用案例[编辑 | 编辑源代码]
实时聊天系统[编辑 | 编辑源代码]
1. 用户A发送消息到WebSocket服务器 2. 服务器广播给所有连接的客户端 3. 用户B实时接收消息
股票行情推送[编辑 | 编辑源代码]
1. 服务器从数据源获取最新价格 2. 通过WebSocket推送至所有订阅的客户端 3. 网页无需刷新即可更新数据
性能优化[编辑 | 编辑源代码]
- 连接池管理:复用TCP连接
- 二进制协议:使用opcode=2减少数据量
- 心跳检测:定期PING/PONG保持连接
安全考虑[编辑 | 编辑源代码]
- 实施wss://(WebSocket Secure)
- 验证Origin头防止CSRF攻击
- 限制帧大小防止内存耗尽
常见问题[编辑 | 编辑源代码]
Q: PHP适合高并发WebSocket吗? A: 原生PHP需配合扩展(如Swoole),纯PHP进程模型效率较低。
Q: 如何检测连接断开? A: 通过onClose回调或心跳超时机制。
参见[编辑 | 编辑源代码]
- RFC 6455 - WebSocket协议标准
- PHP官方文档中的socket扩展
- HTML5 WebSocket API规范
进阶阅读[编辑 | 编辑源代码]
- WebSocket协议帧格式解析
- 负载均衡下的WebSocket集群
- 与HTTP/2的性能对比分析