跳转到内容

PHP WebSocket

来自代码酷

PHP WebSocket[编辑 | 编辑源代码]

WebSocket 是一种在单个TCP连接上进行全双工通信的协议,允许服务器和客户端之间实时交换数据。在PHP中,WebSocket通常用于构建实时应用程序,如聊天系统、在线游戏或股票行情推送等。

简介[编辑 | 编辑源代码]

传统的HTTP协议是无状态的,每次请求都需要建立新的连接。而WebSocket通过一次握手建立持久连接,实现低延迟的双向通信。PHP可以通过扩展库(如Ratchet或Swoole)实现WebSocket服务器。

核心特点[编辑 | 编辑源代码]

  • 全双工通信:客户端和服务器可以同时发送和接收数据。
  • 低延迟:避免HTTP的重复握手开销。
  • 轻量级:数据帧头仅2-10字节。

工作原理[编辑 | 编辑源代码]

WebSocket通信分为两个阶段: 1. 握手阶段:客户端通过HTTP Upgrade头请求切换到WebSocket协议。 2. 数据传输阶段:通过帧(Frame)格式交换数据。

sequenceDiagram Client->>Server: HTTP Upgrade请求 (Connection: Upgrade) Server->>Client: 101 Switching Protocols Note over Client,Server: WebSocket连接建立 Client->>Server: 发送数据帧 Server->>Client: 返回数据帧

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头交换密钥:

Sec-WebSocket-Accept=base64(sha1(Sec-WebSocket-Key+258EAFA5-E914-47DA-95CA-C5AB0DC85B11))

实际应用案例[编辑 | 编辑源代码]

实时聊天系统[编辑 | 编辑源代码]

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的性能对比分析