使用 fetch API 进行流式传输

问题描述 投票:0回答:2

我创建了 .NET Core API,并在其中公开了一个 POST 端点,该端点通过多个块传输响应,其中每个块包含一个 JSON 对象,并且我创建了 Angular 客户端应用程序,通过 fetch API 查询该端点:

const response = await fetch(environment.apiUrl + `/Vehicle/ParseVehiclesData`,
{
  method: 'post',
  body: file,
});

const reader = response.body.getReader();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  let res = JSON.parse(new TextDecoder("utf-8").decode(value));
  console.log(res);
}

我的目标是向进度条提供有关每个块中从服务器返回的进度的信息,现在我遇到的问题是,当连接速度较弱的用户尝试它时,会发生一种行为,他们的速度每个块的消耗小于服务器提要的速度,这会导致浏览器在存在背压时将块合并在一起,因此我尝试解析解码的字符串失败,因为我将尝试解析类似的内容

{"name":"abc","progress":50}{"name":"ab1","progress":100"}

多个 json 对象将被附加在一起,没有分隔符,甚至不换行, 所以我正在寻找的是一种解决方案,可以在存在背压时阻止块的合并,或者在最坏的情况下,找到一种解析没有分隔符的 JSON 对象并将它们提供给自定义流或可观察对象的方法,有关的任何帮助主题将不胜感激。

这些是我在搜索时偶然发现的一些文章, 互联网速度

javascript c# stream fetch-api
2个回答
1
投票

您可以定义一个预解析器来通过

}{
分隔符分割消息(并处理第一个/最后一个条目):

let preParser = (a)=>a.split('}{').map((item,index) => {
       if(a.split('}{').length>1){
          if (index== 0){return item+'}'} // first msg
          else if (index<a.split('}{').length-1){return '{'+item+'}'} // middle msgs
          else {return '{'+item}} // last msg
       else {return a} // no need to do anything if single msg
})

a='{"name":"abc","progress":50}'

b='{"name":"abc","progress":50}{"name":"ab1","progress":100}{"name":"ab2","progress":150}'


console.log('example 1')
preParser(a).forEach(v => console.log(JSON.parse(v)))

console.log('example 2')
preParser(b).forEach(v => console.log(JSON.parse(v)))


0
投票

这对我有帮助,尽管我不使用 Angular - https://nextjs.org/docs/app/building-your-application/routing/route-handlers#streaming

基本上

StreamingTextResponse
来自 Vercel ai 包

© www.soinside.com 2019 - 2024. All rights reserved.