amphp/websocket-client

Amp 基础上的异步 WebSocket 客户端

资助包维护!
amphp

v2.0.0 2023-12-28 01:48 UTC

README

AMPHP 是一套为 PHP 设计的事件驱动库集合,考虑到纤维和并发。 amphp/websocket-client 提供了一个基于 Amp 的异步 WebSocket 客户端。WebSocket 是全双工通信通道,主要用于实时通信,因为 HTTP 请求/响应周期开销太大。如果服务器应该能够在不显式请求的情况下将数据推送到客户端,也可以使用。

PHP 中 WebSocket 客户端的用例很多,例如消费实时 API、编写 WebSocket 服务器的测试或通过基于 WebSocket 的远程调试 API 控制网络浏览器。

安装

此包可以作为 Composer 依赖项安装。

composer require amphp/websocket-client

要求

  • PHP 8.1+

使用方法

连接

您可以使用 Amp\Websocket\connect() 或在 WebsocketConnector 实例上调用 connect() 来创建新的 WebSocket 连接。该 connect() 函数接受一个字符串、PSR-7 UriInterface 实例或一个 WebsocketHandshake 作为第一个参数。URI 必须使用 wswss(WebSocket over TLS)方案。

可以通过传递一个 WebsocketHandshake 对象而不是字符串作为第一个参数来指定自定义连接参数,这也可以用于在初始握手时传递额外的头信息。第二个参数是可选的 Cancellation,可以用来取消连接尝试。

<?php

require 'vendor/autoload.php';

use function Amp\Websocket\Client\connect;

// Amp\Websocket\Client\connect() uses the WebsocketConnection instance
// defined by Amp\Websocket\Client\websocketConnector()
$connection = connect('ws://localhost:1337/websocket');

foreach ($connection as $message) {
    // $message is an instance of Amp\Websocket\WebsocketMessage
}

自定义连接参数

如果需要,可以通过向用于建立 WebSocket 连接的 WebsocketConnector 提供定制的 WebsocketConnectionFactory 实例来更改各种连接参数和行为。

use Amp\Websocket\Client\Rfc6455ConnectionFactory;
use Amp\Websocket\Client\Rfc6455Connector;
use Amp\Websocket\Client\WebsocketHandshake;
use Amp\Websocket\ConstantRateLimit;
use Amp\Websocket\Parser\Rfc6455ParserFactory;
use Amp\Websocket\PeriodicHeartbeatQueue;

$connectionFactory = new Rfc6455ConnectionFactory(
    heartbeatQueue: new PeriodicHeartbeatQueue(
        heartbeatPeriod: 5, // 5 seconds
    ),
    rateLimit: new ConstantRateLimit(
        bytesPerSecondLimit: 2 ** 17, // 128 KiB
        framesPerSecondLimit: 10,
    ),
    parserFactory: new Rfc6455ParserFactory(
        messageSizeLimit: 2 ** 20, // 1 MiB
    ),
    frameSplitThreshold: 2 ** 14, // 16 KiB
    closePeriod: 0.5, // 0.5 seconds
);

$connector = new Rfc6455Connector($connectionFactory);

$handshake = new WebsocketHandshake('wss://example.com/websocket');
$connection = $connector->connect($handshake);

发送数据

可以使用 Connection::sendText()Connection::sendBinary() 方法发送 WebSocket 消息。使用 Connection::sendText() 发送的文本消息必须是有效的 UTF-8。使用 Connection::sendBinary() 发送的二进制消息可以是任意数据。

这两个方法在消息完全写入发送缓冲区后立即返回。这并不意味着消息一定被对方接收。

接收数据

可以使用 Connection::receive() 方法接收 WebSocket 消息。当客户端开始接收消息时,Connection::receive() 返回一个 WebsocketMessage 实例。这允许流式传输 WebSocket 消息,这些消息可能相当大。实际上,大多数消息都很小,可以通过调用 WebsocketMessage::buffer() 或将该对象转换为字符串来完全缓冲。消息的最大长度由提供给 WebsocketConnectionFactoryWebsocketParserFactory 实例的选项定义(默认为 10 MiB)。

use Amp\Websocket\Client\WebsocketHandshake;
use Amp\Websocket\WebsocketCloseCode;
use function Amp\Websocket\Client\connect;

// Connects to the websocket endpoint at libwebsockets.org
// which sends a message every 50ms.
$handshake = (new WebsocketHandshake('wss://libwebsockets.org'))
    ->withHeader('Sec-WebSocket-Protocol', 'dumb-increment-protocol');

$connection = connect($handshake);

foreach ($connection as $message) {
    $payload = $message->buffer();

    printf("Received: %s\n", $payload);

    if ($payload === '100') {
        $connection->close();
        break;
    }
}

版本控制

amphp/websocket-client 遵循与所有其他 amphp 包相同的 semver 语义版本规范。

安全

如果您发现任何安全相关的问题,请使用私人安全问题报告者而不是使用公共问题跟踪器。

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 LICENSE