ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hyperf WebSocket 协程客户端实战:ClientFactory 创建、消息收发与连接生命周期管理

Hyperf WebSocket 协程客户端实战:ClientFactory 创建、消息收发与连接生命周期管理 后端微服务【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/gh_mirrors/hy/hyperf点击查看免费下载本指南以 Hyperf 官方组件hyperf/websocket-client为主线讲解如何在 Hyperf 应用中作为协程客户端连接 WebSocket Server完成消息推送push、响应接收recv以及连接自动关闭控制。读完本文你将掌握基于ClientFactory快速创建客户端、在 HttpServer 等协程环境中收发 WebSocket 消息以及通过$autoClose精确管理连接生命周期的完整实战方案。组件定位Hyperf 对 WebSocket Client 的协程化封装Hyperf 为 WebSocket Client 提供了开箱即用的封装使应用能够以协程的方式访问 WebSocket Server。该能力由独立的 hyperf/websocket-client 组件提供组件目录下包含Client、ClientFactory、Frame、CloseFrame等核心类以及对应的单元测试。从 composer.json 可以看出该组件的运行前提PHP 版本要求 8.2依赖hyperf/contract、hyperf/http-message、hyperf/stringable、hyperf/support与psr/container底层实际使用 Swoole 的Coroutine\Http\Client完成握手与数据传输见 Client.php。组件通过ConfigProvider完成自动注册ConfigProvider.php 返回空配置数组意味着该组件无需额外的业务配置即可使用。安装在 Hyperf 项目中通过 Composer 安装composer require hyperf/websocket-client安装完成后Hyperf\WebSocketClient\ClientFactory与Hyperf\WebSocketClient\Client等类即可通过依赖注入容器自动解析。快速上手在 HttpServer 中创建并收发消息组件提供Hyperf\WebSocketClient\ClientFactory用于创建Hyperf\WebSocketClient\Client客户端对象。以下示例来自官方文档演示在 HttpServer 的控制器内创建 WebSocket 协程客户端向 WebSocket Server 发送数据并接收响应?php declare(strict_types1); namespace App\Controller; use Hyperf\Di\Annotation\Inject; use Hyperf\WebSocketClient\ClientFactory; use Hyperf\WebSocketClient\Frame; class IndexController { #[Inject] protected ClientFactory $clientFactory; public function index() { // 对端服务地址。若不指定 ws:// 或 wss:// 前缀将默认补全为 ws:// $host 127.0.0.1:9502; // 通过 ClientFactory 创建 Client 对象该对象为短生命周期对象 $client $this-clientFactory-create($host); // 向 WebSocket 服务器发送消息 $client-push(Use WebSocket Client to send data in HttpServer.); // 获取服务器响应。服务器需要通过 push 向该客户端的 fd 发送消息才能收到响应 // 设置 2 秒超时接收到的数据类型为 Frame 对象 /** var Frame $msg */ $msg $client-recv(2); // 获取文本数据$msg-data return $msg-data; } }代码要点拆解#[Inject]注解将ClientFactory注入控制器属性这是 Hyperf 标准的依赖注入用法create($host)返回一个Client实例该实例是一次性短生命周期使用对象默认在协程退出时自动关闭push()发送文本消息到服务器recv(2)阻塞等待服务器响应超时时间为 2 秒返回Frame对象文本内容通过$msg-data读取。源码级解析ClientFactory 的创建过程ClientFactory.php 是客户端创建的入口其create方法签名如下public function create(string $uri, bool $autoClose true, array $headers []): Client三个参数的职责参数类型默认值说明$uristring必传对端地址如127.0.0.1:9502或ws://127.0.0.1:9502/ws$autoClosebooltrue是否在协程退出时通过defer自动关闭连接$headersarray[]握手阶段附加的自定义请求头如认证 Token其内部逻辑可拆为三步第一步协议前缀补全。当$uri不以ws://或wss://开头时自动拼接ws://前缀if (! Str::startsWith($uri, [ws://, wss://])) { $uri ws:// . $uri; }因此文档示例中的$host 127.0.0.1:9502最终会被解析为ws://127.0.0.1:9502。第二步容器创建 Client。通过 Hyperf 的make()函数以uri与headers两个构造参数创建Client对象使其能够被容器统一管理和解析。第三步注册协程级自动关闭。当$autoClose为true默认时调用defer()注册一个在协程退出时执行的回调该回调会调用$client-close()if ($autoClose) { defer(function () use ($client) { $client-close(); }); }这保证了在 HttpServer 的一次请求协程中创建的客户端无论业务逻辑是否正常返回都会在协程结束时自动释放连接避免连接泄漏。这是文档中短生命周期对象与默认自动关闭两个表述的源码级依据。源码级解析Client 的握手、收发与关闭Client.php 是核心客户端实现它直接封装了 Swoole 的Coroutine\Http\Client。构造地址解析与 WebSocket 握手构造函数接收Psr\Http\Message\UriInterface $uri与array $headers []内部执行从 URI 中提取host与port并根据 scheme 是否为wss决定是否启用 SSL默认端口规则当 URI 未显式指定端口时wss默认443ws默认80if (empty($port)) { $port $ssl ? 443 : 80; }创建Coroutine\Http\Client($host, $port, $ssl)有自定义请求头时通过setHeaders()注入拼接请求路径path默认/加上查询串?query从 URI query 解析后重新构建调用upgrade($path)发起 WebSocket 握手升级。握手失败时的错误处理非常关键源码通过errCode区分两类失败底层网络错误errCode ! 0抛出携带errCode与errMsg的异常HTTP 层失败使用响应状态码与 Response.php 的getReasonPhraseByCode()生成原因短语。最终统一抛出Hyperf\WebSocketClient\Exception\ConnectException继承自RuntimeException见 ConnectException.phpthrow new ConnectException(sprintf(Websocket upgrade failed by [%s] [%s]., $errCode, $errMsg));push发送数据帧public function push(string $data, int $opcode WEBSOCKET_OPCODE_TEXT, ?int $flags null): boolpush()直接透传至 Swoole 客户端的push()方法支持三个参数$data要发送的字符串内容$opcode帧类型默认为WEBSOCKET_OPCODE_TEXT文本帧可按需改为WEBSOCKET_OPCODE_BINARY二进制帧等$flags可选取值如SWOOLE_WEBSOCKET_FLAG_FIN结束帧或SWOOLE_WEBSOCKET_FLAG_COMPRESS压缩帧。recv接收响应并智能转换帧类型public function recv(float $timeout -1)recv()在$timeout秒内阻塞等待服务器消息并对 Swoole 返回的原始帧做类型转换返回Swoole\WebSocket\CloseFrame时包装为Hyperf\WebSocketClient\CloseFrame返回Swoole\WebSocket\Frame时包装为Hyperf\WebSocketClient\Frame其他返回值如超时返回false原样返回。因此调用方通常需要先判断返回值类型再决定读取文本数据还是关闭码。$timeout默认值为-1表示不超时。close 与析构兜底public function close(): bool { return $this-client-close(); }此外Client实现了__destruct()在对象被销毁时同样会调用close()作为连接回收的兜底保障。消息帧模型Frame 与 CloseFrame文档中示例返回的是Frame对象Frame.php 提供了完整的帧模型属性/方法说明$finish是否为完整帧结束帧$opcode帧操作码如文本帧1、二进制帧2、Ping 帧9$data帧携带的数据文档示例中即服务器返回的文本内容__toString()直接返回$data可被(string)强转getOpcodeDefinition()返回操作码对应的常量名如WEBSOCKET_OPCODE_TEXT未知码返回WEBSOCKET_BAD_OPCODEgetOpcode()/getData()操作码与数据的读取方法当服务器主动关闭连接时recv()返回的是 CloseFrame.php它在Frame基础上增加了$code关闭码默认WEBSOCKET_CLOSE_NORMAL与$reason关闭原因两个属性便于业务侧区分正常收到数据与连接被关闭两种情形。自定义请求头握手阶段的认证与鉴权ClientFactory::create()的第三个参数$headers支持在 WebSocket 握手阶段附加自定义请求头。例如携带认证 Token$client $this-clientFactory-create($host, true, [ x-token your-auth-token, ]);该能力在单元测试 ClientTest.php 的testClientHeaders中得到验证测试将x-token请求头传入客户端连接后向服务器发送headers指令再从服务器返回的 JSON 中还原出请求头并断言 Token 一致证明请求头确实随握手请求送达服务端。控制自动关闭$autoClose 参数如文档所述默认情况下创建的Client对象会在协程结束时通过defer自动关闭连接。如果业务需要在客户端对象创建后跨协程存活、交由调用方手动管理生命周期可在创建时显式传入第二个参数false$autoClose false; $client $clientFactory-create($host, $autoClose);此时协程退出时不会再自动调用close()连接关闭的时机完全由业务代码控制例如在长连接场景中由调用方在合适的时机手动执行$client-close()。测试验证连接失败、收发与请求头的行为边界组件的 tests 目录覆盖了三个关键行为可作为使用参考testClientConnectFailed对不可达地址ws://172.168.1.1:9522创建Client会抛出ConnectException验证握手失败时的异常路径testClientConnected连接本地ws://127.0.0.1:10002/ws后push(ping)并recv(1)断言收到pong验证收发闭环testClientHeaders验证自定义请求头随握手送达服务端。从测试可见Client也可以绕过ClientFactory直接以new Client(new Uri(ws://...))的方式实例化ClientFactory只是附加了协议前缀补全、容器创建与自动关闭管理的便捷入口。注意事项组件依赖 Swoole 的协程客户端能力因此客户端创建与收发操作必须在 Swoole 协程上下文如 HttpServer、Process 等中执行recv()的返回值在超时或连接关闭等场景下并非Frame务必先判断返回类型再访问$data、$code等属性创建客户端时若不指定端口将按ws - 80、wss - 443的默认规则解析与常规 Web 服务端口约定一致短生命周期用法默认$autoClose true适合在请求协程内发起一次连接、收发若干消息的场景需要复用长连接时应传入$autoClose false并自行管理close()时机。赞分享后端微服务【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/gh_mirrors/hy/hyperf点击查看免费下载相关推荐SpacetimeDB 客户端连接实战指南从 DbConnection 建立到生命周期管理SpacetimeDB 客户端连接实战指南从 DbConnection 建立到生命周期管理 本篇技术指南围绕 SpacetimeDB 1.12.0 客户端的核数据库关系型数据库后端Rivet连接管理WebSocket长连接生命周期控制Rivet连接管理WebSocket长连接生命周期控制 还在为WebSocket长连接管理头疼吗复杂的连接状态维护、消息广播、异常处理让你无从下手Rive后端AI Agent人工智能流程编排WebSocketSpacetimeDB 客户端连接完全指南DbConnection 构建器、WebSocket 生命周期与多语言实践SpacetimeDB 客户端连接完全指南DbConnection 构建器、WebSocket 生命周期与多语言实践 本篇技术指南系统讲解 Spacetime数据库关系型数据库后端上一篇终极指南用MouseTracks可视化你的数字足迹发现隐藏的操作模式下一篇5分钟掌握iwck键盘鼠标防误触工具实战应用全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表