websocket请求通过IteratorAggregate实现流式输出

对接国内讯飞星火模型,官方文档接口采用的是websocket跟国外chatgpt有些差异。

虽然官网给出一个简单demo通过while(true),websocket的receive()可以实现逐条接受并输出给前端,但是通用和灵活度不高。不能兼容现有项目框架的流式输出。故模仿openai,采用IteratorAggregate接口实现迭代器可遍历获取响应结果。

IteratorAggregate只有一个需要实现的方法getIterator()实现起来简单方便,基本代码如下

php 复制代码
<?php
declare(strict_types=1);

namespace App\Extends;

use WebSocket\Client;
use IteratorAggregate;
use Generator;

class XingHuoClient
{
    protected $client;

    public function client(){
        $apikey = '';//自己填写真实内容
        $apiSecret = '';//自己填写真实内容
        $addr = '';//自己填写真实内容
        $authUrl = $this->assembleAuthUrl("GET",$addr,$apikey,$apiSecret);
        //创建ws连接对象
        $this->client = new Client($authUrl);
        return $this;
    }

    public function send($uid, array $message)
    {
        if($this->client){
            $data = $this->getBody($uid, $message);
            $this->client->send($data);
            $response = new XingResponseIterator($this->client);
            return $response;
        }else{
            throw new \Exception('星火客户端异常');
        }
    }

    //构造参数体
    protected function getBody($uid, $message){
        //...省略内容
        return $json_string;
    }

    //鉴权方法
    public function assembleAuthUrl($method, $addr, $apiKey, $apiSecret) {
        //...省略内容
        return $authAddr;
    }
}

class XingResponseIterator implements IteratorAggregate {

    protected $client;

    public function __construct($client) {
        $this->client = $client;
    }

    public function getIterator(): Generator {
        if($this->client){
            while(true){
                $response = $this->client->receive();
                $resp = json_decode($response,true);
                $code = $resp["header"]["code"];
                if(0 == $code){
                    $status = $resp["header"]["status"];
                    if($status != 2){
                        yield $resp['payload'];
                    }else{
                        yield $resp['payload'];
                        break;
                    }
                }else{
                    //TODO:记录错误日志或报警

                    break;
                }
            }
        }else{
            return [];
        }
    }
}

前提引入composer require textalk/websocket包用于socket请求星火接口,大部分内容还是官网提供的demo,主要是增加了XingResponseIterator 。

php 复制代码
$stream = xinghuo()->client()->send($uid, $messages);//xinghuo()是封装的XingHuoClient对象
foreach($stream as $response){
    //处理数据,格式化数据,统计,记录等操作,输出内容到响应流,此处不做细讲
}

输出形式可以分流式输出,以openai为例参考:

https://github.com/orhanerday/open-ai

https://packagist.org/packages/hhxsv5/php-sse

前端浏览器使用的是EventSource对象。

可以使用chunk形式,存在客户端不支持eventSource对象的情况可以选择使用,参考我的另一篇文章

https://blog.csdn.net/jinborui2/article/details/132325824

以及一些nginx配置和php配置也在这篇文章里有所讲解,保证服务端及时输出内容到客户端。

相关推荐
请数据别和我作队1 天前
Python实现直播弹幕数据采集(WebSocket实时弹幕采集)
开发语言·网络·python·websocket·网络协议·学习分享
bkspiderx1 天前
libwebsockets 详解:介绍、交叉编译与使用指南
c++·websocket·libwebsockets
“愿你如星辰如月”1 天前
从零构建高性能 Reactor 服务器:
linux·服务器·c++·websocket·tcp/ip
患得患失9492 天前
【前端WebSocket】心跳功能,心跳重置策略、双向确认(Ping-Pong) 以及 指数退避算法(Exponential Backoff)
前端·websocket·算法
患得患失9492 天前
【前端websocket】企业级功能清单
前端·websocket·网络协议
芯智工坊2 天前
第17章 Mosquitto WebSocket支持
网络·websocket·网络协议
The_Ticker3 天前
印度股票实时行情API(低成本方案)
python·websocket·算法·金融·区块链
2501_921649493 天前
低延迟量化交易数据 API:从架构设计到性能优化的完整实践指南
python·websocket·金融·量化
预立科技3 天前
SSE、WebSocket 和 HTTP
websocket·网络协议·http·sse
AugustRed5 天前
AI流式输出方案SSE vs WebSocket对比
人工智能·websocket·网络协议