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

ai流式文字返回前端和php的处理办法

PHP后端

php端主要是用到ob_flushflush,头改为流式。

基本代码

代码如下:

<?php
header('Content-Type:text/event-stream');
header('Cache-Control:no-cache');
header('Connection:keep-alive');function streamPostRequest($url,$data){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_POST,true);curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($data));curl_setopt($ch,CURLOPT_HTTPHEADER,['Content-Type:application/json','Accept:text/event-stream']);curl_setopt($ch,CURLOPT_WRITEFUNCTION,function($ch,$data){//如果数据不需要特殊处理,这里可以直接返回echo $data;ob_flush();flush();//这里返回数据的长度,如果有特殊处理需要返回处理后的数据长度return strlen($data);});curl_exec($ch);curl_close($ch);
}

以上代码数据没有特殊处理,数据都会被前端接受到。如果特殊处理前端可能需要在done为true时候接收最后一条数据。

数据特殊处理

如果对数据进行处理,在CURLOPT_WRITEFUNCTION中写,代码如下:

<?phpcurl_setopt($ch,CURLOPT_WRITEFUNCTION,function($ch,$data){$start=strpos($data,'{');$end=strrpos($data,'}');$dataContentStr=substr($data,$start,$end-$start);$dataContent=json_decode($dataContentStr,true);$r='';if($dataContent['docs']){//如果这里逻辑复杂,会导致数据返回延迟,需要在前端done为true时接收/*code....*/$r=$data.'test';}else{$r=$data;}echo $r;ob_flush();flush();//这里为最终数据的长度return strlen($r);});

方法的使用

注意这里要使用file_get_contents接受数据

<?php
//要使用file_get_contents接受数据
$data=file_get_contents('php://input')$dataArray=json.decode($data,true);$content=$dataArray['content'];$json=['query'=>$content,
];streamPostRequest("http://127.0.0.1:80/test",$json);

前端

基本代码

用的fetch请求方法,这个可以传数据

var abortController:any=null
var generteSwich=false    //中断请求用的
var maxTime=0async function fetchStreamWithToken(url:string,data:any){abortController=new AbortController()var i=0const response=await fetch(url,{method:'POST',headers:{'Content-Type':'application/json','Accept':'text/event-stream','token':getToken() as any,},body:JSON.stringify($data),signal:abortController.signal})//获取可读流const reader=response.body?.getReader()const decoder=new TextDecoder('utf-8')let buffer:any=''generateSwich=truewhile(true){const {done,value}:any=await reader?.read()if(done || !generateSwich){//如果php数据没直接返回,数据进行特殊处理后返回,需要接受最后数据let endData=buffer//结束setTimeout(()=>{//对最后一个数据的处理,处理逻辑按照需求写const end=JSON.parse()if(end.test){//code...}//更新会话方法updateDialogue()generateSwich=false  //停止dialogueList.value[diaId][lth-1].state='success'},maxTime)break}buffer+=decoder.decode(value,{steam:true})//按行展开const lines=buffer.split('\n')buffer=lines.pop()for(const line of lines){if(line){try{const start=line.indexOf('{')const end=line.lastIndexOf('}')if(start===-1 || end===-1){continue;}const content=line.substring(start,end+1)const parsed=JSON.parse(content)let t=parsed.textsetTimeout(()=>{if(!generateSwich){r    eturn}dialogueList.value[diaId][lth-1].content+=tif(!dialogueList.value[diaId][lth-1].message_id){dialogueList.value[diaId][lth-1].message_id=parsed.message_id}},60*i)i++maxTime=60*i}catch(error){console.log(error)console.log('原始数据',line)}}}}
}

结束思考方法

//停止思考
function stopThinking(){abortController.abort()generateSwich=false
}

http://www.xdnf.cn/news/12522.html

相关文章:

  • Mac下Android Studio扫描根目录卡死问题记录
  • 从0开始学习R语言--Day18--分类变量关联性检验
  • python打卡day46@浙大疏锦行
  • Charles 全流程指南:安装、设置、抓包与注意事项
  • PDF 转 Markdown
  • 【JVM】Java虚拟机(一)——内存结构
  • SSH实现服务器之间免密登录
  • python 爬虫工具 mitmproxy, 几问几答,记录一下
  • 关于华为仓颉编程语言
  • 从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
  • [大A量化专栏] 夏普比率
  • 动力电池点焊机:驱动电池焊接高效与可靠的核心力量|比斯特自动化
  • 【ubuntu】虚拟机安装配置,sh脚本自动化,包含 apt+时间同步+docker+mysql+redis+pgsql
  • 如何理解OSI七层模型和TCP/IP四层模型?HTTP作为如何保存用户状态?多服务器节点下 Session方案怎么做
  • 大模型低秩微调技术 LoRA 深度解析与实践
  • MySQL全文索引
  • pg数据库表里面id值,使用sql语句赋值,唯一性
  • 小知识点一:无刷电机
  • rocketmq延迟消息的底层原理浅析
  • 多航态无人艇航态变换姿态控制系统设计与实现_可复现,有问题请联系博主
  • HZOJ新手村前段时间的刷题的笔记
  • 国内软件源镜像站一览表(2025年状态更新)
  • 使用Python做bootloader下载程序
  • Linux系统删除文件后的恢复方法
  • 1.2 fetch详解
  • 【高等数学】函数项级数
  • Langchain构建聊天机器人
  • 大模型微调(5):PEFT 微调 Qwen 大模型
  • STL优先级队列的比较函数与大堆小堆的关系
  • Kubernetes任务调度:深入理解Job与CronJob