在 PHP 中,WebSocket 提供了一种建立持久性连接并进行双向通信的方式,通常用于实时应用,如聊天室、实时通知、游戏等。WebSocket 协议在客户端和服务器之间保持一个持久的连接,因此可以实现低延迟的实时数据交换。

目录

  1. WebSocket 简介
  2. WebSocket 与 HTTP 的区别
  3. PHP 实现 WebSocket 的方法
    • 3.1 使用 Ratchet 库
    • 3.2 使用 Swoole 扩展
  4. WebSocket 客户端
  5. 实时通信的典型场景
  6. 总结

1. WebSocket 简介

WebSocket 是一种网络通信协议,旨在通过在客户端和服务器之间建立持久的全双工连接,提供低延迟、实时的数据传输。WebSocket 协议通过 ws://wss://(加密版本)协议与 HTTP 协议兼容。

WebSocket 的工作原理:

  1. 握手阶段:客户端发起 HTTP 请求,并通过 Upgrade 头请求将协议升级为 WebSocket。
  2. 连接阶段:服务器接受 WebSocket 请求并响应,连接成功后,客户端和服务器之间的通信将切换到 WebSocket 协议。
  3. 数据传输阶段:客户端和服务器可以通过 WebSocket 持久连接,双向发送数据。

2. WebSocket 与 HTTP 的区别

特性 HTTP WebSocket
连接模式 一次请求/响应模式 持久连接,全双工通信
数据交换 请求-响应模式,客户端发起请求 客户端和服务器可以随时发送消息
延迟 请求/响应后关闭连接 实时、低延迟通信
协议 基于文本,数据通过HTTP请求传输 通过 ws://wss:// 实现

WebSocket 相比 HTTP 在需要双向实时通信的应用中有显著优势,尤其适用于需要快速响应的场景。


3. PHP 实现 WebSocket 的方法

3.1 使用 Ratchet 库

Ratchet 是一个流行的 PHP WebSocket 实现,允许 PHP 服务器通过 WebSocket 协议进行实时通信。它基于 ReactPHP,提供了异步处理和高效的事件驱动机制。

安装 Ratchet
  1. 安装 ratchet/ratchetcboden/ratchet
composer require cboden/ratchet
  1. 安装 react/socketreact/event-loop,这是 Ratchet 所依赖的库。
composer require react/socket react/event-loop
示例代码:创建一个 WebSocket 服务器
<?php

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;

require dirname(__DIR__) . '/vendor/autoload.php';

class Chat implements MessageComponentInterface
{
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        echo "New connection: {$conn->resourceId}\n";
        $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        echo "New message: $msg\n";
        // 广播消息给所有连接的客户端
        foreach ($this->clients as $client) {
            if ($from !== $client) {
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        echo "Connection {$conn->resourceId} closed\n";
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "Error: {$e->getMessage()}\n";
        $conn->close();
    }
}

// 创建并启动 WebSocket 服务器
$server = IoServer::factory(
    new WsServer(
        new Chat()
    ),
    8080
);

$server->run();
启动 WebSocket 服务器

运行 PHP WebSocket 服务器:

php your-script.php
客户端 JavaScript 示例:
const socket = new WebSocket('ws://localhost:8080');

socket.onopen = function() {
    console.log('WebSocket connection established.');
    socket.send("Hello Server");
};

socket.onmessage = function(event) {
    console.log('Message from server: ' + event.data);
};

socket.onclose = function() {
    console.log('WebSocket connection closed.');
};

3.2 使用 Swoole 扩展

Swoole 是一个高性能的 PHP 扩展,提供了用于 WebSocket 的支持,适用于需要处理大量并发连接的场景。它提供了多进程、协程、异步 I/O 等功能,非常适合高并发的 WebSocket 服务。

安装 Swoole

首先,你需要安装 Swoole 扩展:

pecl install swoole
示例代码:创建一个 WebSocket 服务器
<?php
// 创建 WebSocket 服务器
$server = new Swoole\WebSocket\Server("0.0.0.0", 9502);

$server->on("open", function($server, $request) {
    echo "Connection established: " . $request->fd . "\n";
});

$server->on("message", function($server, $frame) {
    echo "Message received: " . $frame->data . "\n";
    $server->push($frame->fd, "Hello, client");
});

$server->on("close", function($server, $fd) {
    echo "Connection closed: " . $fd . "\n";
});

// 启动服务器
$server->start();
?>
客户端 JavaScript 示例:
const socket = new WebSocket('ws://localhost:9502');

socket.onopen = function() {
    console.log('Connection established');
    socket.send('Hello Server');
};

socket.onmessage = function(event) {
    console.log('Message from server: ' + event.data);
};

启动服务器后,客户端可以与其建立连接并进行通信。


4. WebSocket 客户端

WebSocket 客户端可以使用 JavaScript 在浏览器端进行连接和数据交换。常见的浏览器 WebSocket 客户端代码如下:

const socket = new WebSocket("ws://localhost:8080");

socket.onopen = function() {
    console.log("Connected to WebSocket server");
    socket.send("Hello from client!");
};

socket.onmessage = function(event) {
    console.log("Received message: " + event.data);
};

socket.onclose = function() {
    console.log("Connection closed");
};

在浏览器中,WebSocket 客户端连接到服务器时,将建立一个持久化的连接,并且可以随时发送和接收消息。


5. 实时通信的典型场景

  • 聊天室:WebSocket 非常适合实现聊天室功能,支持多个客户端之间的实时消息推送。
  • 实时通知:例如,社交媒体平台可以通过 WebSocket 向用户实时推送通知。
  • 在线游戏:WebSocket 可用于实现多人游戏的实时交互。
  • 金融市场:WebSocket 常用于股票、货币交易等金融领域,实时传输市场数据。
  • 实时协作应用:例如,Google Docs 风格的实时文档编辑。

6. 总结

通过使用 RatchetSwoole,你可以轻松地在 PHP 中实现 WebSocket 服务,并通过客户端与服务器建立双向通信。WebSocket 提供了一个低延迟、持久连接的通信方式,非常适用于实时应用程序。无论是用 Ratchet 构建简单的聊天应用,还是用 Swoole 构建高并发的 WebSocket 服务,这些工具都能帮助你轻松实现实时通信功能。