当前位置: 首页 > news >正文

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

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

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

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

<?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 。

$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配置也在这篇文章里有所讲解,保证服务端及时输出内容到客户端。

相关文章:

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

对接国内讯飞星火模型&#xff0c;官方文档接口采用的是websocket跟国外chatgpt有些差异。 虽然官网给出一个简单demo通过while(true)&#xff0c;websocket的receive()可以实现逐条接受并输出给前端&#xff0c;但是通用和灵活度不高。不能兼容现有项目框架的流式输出。故模仿…...

《C和指针》笔记28:可变参数和stdarg宏

可变参数列表可以通过宏来实现&#xff0c;这些宏定义于stdarg.h头文件&#xff0c;它是标准库的一部分。这个头文件声明了一个类型va_list和三个宏——va_start、va_arg和va_end 。我们可以声明一个类型为va_list的变量&#xff0c;与这几个宏配合使用&#xff0c;访问参数的值…...

Matlab论文插图绘制模板第114期—带图形标记的图

之前的文章中&#xff0c;分享了Matlab带线标记的图&#xff1a; 带阴影标记的图&#xff1a; 带箭头标记的图&#xff1a; 进一步&#xff0c;分享一下带图形标记的图&#xff0c;先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&…...

Python:用于有效对象管理的单例模式

1. 写在前面 在本文中&#xff0c;我们将介绍一种常用的软件设计模式 —— 单例模式。 通过示例&#xff0c;演示单例创建&#xff0c;并确保该实例在整个应用程序生命周期中保持一致。同时探讨它在 Python 中的目的、益处和实际应用。 关键点&#xff1a; 1、单例模式只有…...

【TCP】滑动窗口、流量控制 以及拥塞控制

滑动窗口、流量控制 以及拥塞控制 1. 滑动窗口&#xff08;效率机制&#xff09;2. 流量控制&#xff08;安全机制&#xff09;3. 拥塞控制&#xff08;安全机制&#xff09; 1. 滑动窗口&#xff08;效率机制&#xff09; TCP 使用 确认应答 策略&#xff0c;对每一个发送的数…...

Xilinx FPGA管脚约束语法规则(UCF和XDC文件)

文章目录 1. ISE环境&#xff08;UCF文件&#xff09;2. Vivado环境&#xff08;XDC文件&#xff09; 本文介绍ISE和Vivado管脚约束的语句使用&#xff0c;仅仅是管脚和电平状态指定&#xff0c;不包括时钟约束等其他语法。 ISE使用UCF文件格式&#xff0c;Vivado使用XDC文件&…...

服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

代码随想录训练营第56天|583.两个字符串的删除操作,72.编辑距离

代码随想录训练营第56天|583.两个字符串的删除操作&#xff0c;72.编辑距离 583.两个字符串的删除操作文章思路代码 72.编辑距离文章思路代码 总结 583.两个字符串的删除操作 文章 代码随想录|0583.两个字符串的删除操作 思路 如果不按照编辑距离考虑的话&#xff0c;只需要…...

【JDK 8-Lambda】3.1 Java高级核心玩转 JDK8 Lambda 表达式

一、 什么是函数式编程 &#xff1f; 二、 什么是lambda表达式&#xff1f; 1. 先看两个示例 A.【创建线程】 B.【数组排序-降序】 2. lambda表达式特性 A. 使用场景(前提): B. 语法 (params) -> expression C. 参数列表 D. 方法体 F. 好处 一、 什么是函数式编…...

【C#】XML的基础知识以及读取XML文件

最近在学读取文件 目录 介绍特点结构XML的语法规则XML 命名规则 C#操作XML新建读取第一种第二种第三种 读取属性 介绍 XML (可扩展标记语言&#xff0c;eXtensible Markup Language) 是一种标记语言&#xff0c;它被设计用来传输和存储数据。 特点 可扩展性&#xff1a;由于…...

Immutable.js简介

引子 看一段大家熟悉的代码 const state {str: wwming,obj: {y: 1},arr: [1, 2, 3] } const newState stateconsole.log(newState state) // truenewState和state是相等的 原因&#xff1a; 由于js的对象和数组都是引用类型。所以newState的state实际上是指向于同一块内存…...

C语言进阶教程(位操作和进制数的表示)

文章目录 前言一、左移和右移二、清除对应的位为0和设置对应的位为11.设置对应的位为12.清除对应的位为0 三、进制数的表示四、& ^ | ~总结 前言 本篇文章给大家讲解一下C语言中的位操作&#xff0c;在嵌入式中位操作是经常需要使用的&#xff0c;那么下面就让我们来学习一…...

Loguru:功能强大、简单易用的Python日志库

文章目录 Loguru:Python的日志库安装 Loguru基本用法配置 Loguruadd() 语句remove() 语句设置日志文件保留日志的等级设置控制台日志显示等级Loguru:Python的日志库 Loguru 是一个功能强大、简单易用的日志库,可以让 Python 的日志记录变得更加轻松。它提供了丰富的功能和配…...

idea之maven的安装与配置

我们到maven的官网里下载maven&#xff0c;地址&#xff1a;https://maven.apache.org/download.cgi下载完成后解压即可配置环境变量 此电脑–>右键–>属性–>高级系统设置–>环境变量–>系统变量&#xff08;S&#xff09;–>新建一个系统变量 变量名&…...

【最新面试问题记录持续更新,java,kotlin,android,flutter】

最近找工作&#xff0c;复习了下java相关的知识。发现已经对很多概念模糊了。记录一下。部分是往年面试题重新整理&#xff0c;部分是自己面试遇到的问题。持续更新中~ 目录 java相关1. 面向对象设计原则2. 面向对象的特征是什么3. 重载和重写4. 基本数据类型5. 装箱和拆箱6. …...

面试:经典问题解决思路

1. 秒杀系统架构 参考&#xff1a;秒杀系统架构优化思路 2. 如何防止订单重复提交 重复提交原因: 一种是由于用户在短时间内多次点击下单按钮&#xff0c;或浏览器刷新按钮导致。另一种则是由于Nginx或类似于SpringCloud Gateway的网关层&#xff0c;进行超时重试造成的。 方案…...

CG MAGIC分享3ds Max卡顿未保存处理方法有哪些?

3ds Max进行建模、渲染这一系列过程中&#xff0c;大家使用中都会遇到各种原因导致软件卡顿或崩溃是很常见的情况。 可以说卡机没关系&#xff0c;可是卡顿发生时&#xff0c;如果之前的工作没有及时保存&#xff0c;可能会导致数据的丢失和时间的浪费。这就是最让人烦躁的了&…...

[python 刷题] 238 Product of Array Except Self

[python 刷题] 238 Product of Array Except Self 题目&#xff1a; Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i]. The product of any prefix or suffix of nums is guar…...

UG NX二次开发(C#)-计算直线到各个坐标系轴向的投影角度

文章目录 1、前言2、需求分析3、NXOpen方法实现3.1 创建基准坐标系3.2 然后计算直线到基准坐标系的轴向角度3.3 代码调用4、测试效果为:1、前言 最近有个粉丝问我如何计算直线到坐标系各个轴向的角度,这里用UG NX二次开发(C#)实现。当然,这里的内容是经验之谈,如果有更好的…...

C# ComboBox 和 枚举类型(Enum)相互关联

C# ComboBox 和 枚举类型(Enum)相互关联 目的 在C# Winform面板上的ComboBox选择项&#xff0c;由程序填写某个Enum的各个枚举项目。 在运行中读取ComboBox的选择项&#xff0c;返回Enum数值。 非编程方法 低阶做法可以在winform设计窗口手动填写&#xff0c;但是不会自动跟…...

Linux CentOS7 tree命令

tree就是树&#xff0c;是文件或文件名输出到控制台的一种显示形式。 tree命令作用&#xff1a;以树状图列出目录的内容&#xff0c;包括文件、子目录及子目录中的文件和目录等。 我们使用ll命令显示只能显示一个层级的普通文件和目录的名称。而使用tree则可以树的形式将指定…...

软件设计模式系列之九——桥接模式

1 模式的定义 桥接模式是一种结构型设计模式&#xff0c;它用于将抽象部分与其实现部分分离&#xff0c;以便它们可以独立地变化。这种模式涉及一个接口&#xff0c;它充当一个桥&#xff0c;使得具体类可以在不影响客户端代码的情况下改变。桥接模式将继承关系转化为组合关系…...

构造函数的调用规则

#include <iostream> #include <string> using namespace std; class person{ public:int m_age; // person(){ // cout<<"默认构造的调用"<<endl; // } // person(int age){ // m_ageage; // cout<<"有参构造的调用"<…...

第十章:枚举类与注解

10.1&#xff1a;枚举类的使用 当需要定义一组常量时&#xff0c;建议使用枚举类&#xff08;前提&#xff1a;类的对象只有有限个&#xff0c;确定的&#xff09; eg&#xff1a; 星期&#xff1a;Mondey、.....、Sunday 性别&#xff1a;Man、.....、Woman 线程状态&#xff…...

ChatGPT:字符串操作问题——提取包含括号的字符串中的题干内容

ChatGPT&#xff1a;字符串操作问题——提取包含括号的字符串中的题干内容 String title p.text().split(“(”)[0];为什么会报错 ChatGPT&#xff1a; 在这段代码中&#xff0c;您正在使用Java处理一个字符串&#xff08;假设是HTML或文本&#xff09;&#xff0c;尝试将其分…...

jvm中对象创建、内存布局以及访问定位

对象创建 Java语言层面&#xff0c;创建对象通常&#xff08;例外&#xff1a;复制、反序列化&#xff09;仅仅是一个new关键字即可&#xff0c;而在虚拟机中&#xff0c;对象&#xff08;限于普通Java对象&#xff0c;不包括数组和Class对象等&#xff09;的创建又是怎样一个过…...

C基础-操作符详解

操作符分类&#xff1a; 算数操作符&#xff1a; - * / % //算数操作符 // int main() // { // // /除法 1.整数除法(除号两端都是整数) 2浮点数除法&#xff0c;除号的两端只要有一个小数就执行小数除法 // // 除法中&#xff0c;除数为0 // int a 7 / 2; /…...

时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测

时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测 目录 时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测。…...

【深度学习实验】线性模型(五):使用Pytorch实现线性模型:基于鸢尾花数据集,对模型进行评估(使用随机梯度下降优化器)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 线性模型linear_model 2. 损失函数loss_function 3. 鸢尾花数据预处理 4. 初始化权重和偏置 5. 优化器 6. 迭代 7. 测试集预测 8. 实验结果评估 9. 完整代码 一、实验介…...

ADB底层原理

介绍 adb的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用。通过adb我们可以在Eclipse/Android Studio中方便通过DDMS来调试Android程序&#xff0c;说白了就是debug工具。adb是android sdk里的一个工具, 用这个工具可以直接操作管理android模拟器或者真实的and…...

图库网站建设/营销策划主要做些什么

起初照着官方文档配&#xff0c;一直出错&#xff0c;貌似官方的文档时错的&#xff0c;查了非常多资料&#xff0c;综合整理了一个可行的方案&#xff0c;例如以下&#xff1a; 0.1包结构 test.demo test.domain //实体类 test.util//工具类 0.2导如的jar包 hibernate-4.3.5的…...

网站引入百度地图/网络推广怎么推广

一.管理输入和输出 在系统中利用普通用户执行命令’find /etc -name passwd’&#xff0c;由于普通用户权限问题&#xff0c;将会出现两种输出&#xff1a;正确输出和错误输出 因为student用户权限问题会有以下输出find: ‘/etc/pki/CA/private’: Permission denied ##没有进…...

公司网站做的一样算不算侵权/哈尔滨seo网站管理

this在js中有着非常广泛的应用&#xff0c;但其所指的对象也常常让人摸不着头脑&#xff0c;简而言之: this指的就是调用函数的对象&#xff0c;最常见的莫过以下几种 1.直接使用函数&#xff0c;则为window对象 function a(){this.a 1console.log(this) } a() //window对象 wi…...

app网站及其特色/360推广登录

HTML DOM getElementsByClassName() 方法实例获取所有指定类名的元素&#xff1a;var x document.getElementsByClassName("example");尝试一下 定义和使用getElementsByClassName() 方法返回文档中所有指定类名的元素集合&#xff0c;作为 NodeList 对象。NodeList…...

湖北省住房和城乡建设厅网站的公示公告/360开户推广

尤拉公式----关于凸多面体之间顶点数/面数/边数之间的关系 若G为一连通之平面图,则V F E 2其中V代表G中点的个数, F代表G中面的个数, 而E是G的边数. 应用&#xff1a;在一个圆上给你n个点&#xff0c;求n个点可以把圆分为几个区域 分析&#xff1a;根据欧拉定理可知&#xf…...

微信分销系统价格/seo优化代理

在日志中记录Java异常信息的正确姿势参考文章&#xff1a; &#xff08;1&#xff09;在日志中记录Java异常信息的正确姿势 &#xff08;2&#xff09;https://www.cnblogs.com/nuccch/p/11061929.html 备忘一下。...