当前位置:首页 > PHP

php实现websocket

2026-01-13 12:51:37PHP

PHP 实现 WebSocket

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。PHP 可以通过多种方式实现 WebSocket 功能,以下是几种常见的方法:

使用 Ratchet 库

Ratchet 是一个流行的 PHP WebSocket 库,基于 ReactPHP 实现。安装 Ratchet 可以通过 Composer:

composer require cboden/ratchet

创建一个简单的 WebSocket 服务器:

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

class MyWebSocket implements MessageComponentInterface {
    public function onOpen(ConnectionInterface $conn) {
        echo "New connection: {$conn->resourceId}\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        echo "Received message: {$msg}\n";
        $from->send("Echo: {$msg}");
    }

    public function onClose(ConnectionInterface $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();

运行服务器后,可以通过 JavaScript 客户端连接到 ws://localhost:8080

使用 Swoole 扩展

Swoole 是一个高性能的 PHP 协程框架,内置 WebSocket 支持。安装 Swoole:

pecl install 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 (Swoole\WebSocket\Server $server, $frame) {
    echo "Received message: {$frame->data}\n";
    $server->push($frame->fd, "Echo: {$frame->data}");
});

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

$server->start();

运行服务器后,可以通过 JavaScript 客户端连接到 ws://localhost:9501

使用原生 PHP 和 Socket 函数

对于更底层的实现,可以使用 PHP 的 Socket 函数。以下是一个简单的示例:

$host = '0.0.0.0';
$port = 8080;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);

while (true) {
    $client = socket_accept($socket);
    $request = socket_read($client, 1024);

    if (preg_match('/Sec-WebSocket-Key: (.*)\r\n/', $request, $match)) {
        $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
        $headers = "HTTP/1.1 101 Switching Protocols\r\n";
        $headers .= "Upgrade: websocket\r\n";
        $headers .= "Connection: Upgrade\r\n";
        $headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
        socket_write($client, $headers, strlen($headers));
    }

    while (true) {
        $data = socket_read($client, 1024);
        if ($data === false) break;
        $decoded = decodeWebSocket($data);
        echo "Received: {$decoded}\n";
        $encoded = encodeWebSocket("Echo: {$decoded}");
        socket_write($client, $encoded, strlen($encoded));
    }

    socket_close($client);
}

function decodeWebSocket($data) {
    $length = ord($data[1]) & 127;
    $mask = substr($data, 2, 4);
    $payload = substr($data, 6);
    $decoded = '';
    for ($i = 0; $i < $length; $i++) {
        $decoded .= $payload[$i] ^ $mask[$i % 4];
    }
    return $decoded;
}

function encodeWebSocket($text) {
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);
    $header = '';
    if ($length <= 125) {
        $header = pack('CC', $b1, $length);
    } elseif ($length > 125 && $length < 65536) {
        $header = pack('CCn', $b1, 126, $length);
    } else {
        $header = pack('CCNN', $b1, 127, $length);
    }
    return $header . $text;
}

这种方法需要手动处理 WebSocket 协议,适合学习 WebSocket 底层原理。

客户端连接示例

无论使用哪种服务器实现,客户端都可以通过以下 JavaScript 代码连接:

const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => console.log('Connected');
socket.onmessage = (e) => console.log('Received:', e.data);
socket.onclose = () => console.log('Disconnected');
socket.send('Hello, WebSocket!');

注意事项

  • WebSocket 服务器需要长时间运行,建议使用 Supervisor 或 Systemd 管理进程。
  • 生产环境建议使用成熟的库如 Ratchet 或 Swoole,避免手动实现协议。
  • 注意处理连接异常和资源释放,避免内存泄漏。

php实现websocket

标签: phpwebsocket
分享给朋友:

相关文章

php实现分页

php实现分页

PHP实现分页的基本方法 使用原生PHP实现分页功能需要结合数据库查询和HTML展示。以下是核心实现步骤: 数据库查询与分页逻辑 // 连接数据库 $conn = new mysqli('lo…

php实现文件下载

php实现文件下载

PHP 实现文件下载的方法 使用 header() 函数强制下载 设置正确的 HTTP 头信息,强制浏览器下载文件而不是直接打开。 $file = 'path/to/file.pdf'; if (…

php实现搜索功能

php实现搜索功能

实现基础搜索功能 使用PHP和MySQL实现基础的搜索功能需要结合表单提交与数据库查询。创建一个HTML表单用于接收用户输入的搜索关键词,通过PHP处理表单数据并查询数据库。 // 搜索表单 (H…

php实现打印功能

php实现打印功能

PHP 实现打印功能的方法 PHP 可以通过多种方式实现打印功能,具体取决于打印的目标(如打印机、PDF、网页等)和需求(如直接打印、生成打印预览等)。以下是几种常见的实现方式: 使用 JavaSc…

php实现文件上传

php实现文件上传

PHP 文件上传实现方法 在 PHP 中实现文件上传需要处理 HTML 表单和服务器端脚本。以下是详细步骤: 创建 HTML 表单 使用 enctype="multipart/form-data"…

vue实现websocket

vue实现websocket

Vue 实现 WebSocket 连接 在 Vue 项目中实现 WebSocket 连接,可以通过原生 WebSocket API 或第三方库(如 socket.io-client)完成。以下是两种方…