如何在React Native中实现流式传输?

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

我正在尝试在 React Native 应用程序中实现流式传输,但遇到了问题。具体来说,我使用

react-native-fetch-api
库和
react-native-polyfill-globals
来发出流请求,但它似乎没有按预期工作。

我读过这篇文章:在react-native应用程序中使用fetch流式传输api

无法让它工作。经过一番调试,我想出了这个:

import 'react-native-polyfill-globals/auto';
import { fetch as fetchh } from 'react-native-fetch-api';

const streamBotResponse = async () => {
  const response = await fetchh(
    'URL...', 
    {
      headers: {
        ...
      },
      reactNative: { textStreaming: true },
    }
  );

  async function* streamAsyncIterator(stream: ReadableStream) {
    const reader = stream.getReader();
    try {
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        yield value;
      }
    } finally {
      reader.releaseLock();
    }
  }

  for await (const chunk of streamAsyncIterator(response.body)) {
    console.log(new TextDecoder().decode(chunk));
  }
};

似乎无法解决:找不到模块“react-native-fetch-api”的声明文件。 在我看来,这个库不支持 TypeScript (我可以使用 d.ts 文件解决错误,但没有用于 react-native-fetch-api 的 @types 库(react-native-polyfill-globals 也是如此) )

但这并不是一个大问题,我设法让它正常工作,但我的整个流响应以 1 块的形式返回给我。是否有可能将其分成多个较小的块来恢复?或者这是 RN 的限制,我应该放弃这个吗?

javascript react-native streaming
1个回答
0
投票
由于框架内流处理方式的限制,React Native 中的流处理可能具有挑战性。然而,处理流的一种方法是使用 WebView 来利用浏览器的本机流功能。

我设法让它像这样工作:

... import { WebView, WebViewMessageEvent } from 'react-native-webview'; const StreamComponent = () => { const webviewRef = useRef<WebView>(null); const [message, setMessage] = useState<string>(''); const getStreamData = () => { setMessage(''); const injectScript = ` (async()=>{ const response = await fetch('YOUR_STREAM_URL/stream', { method: 'GET', responseType: 'stream', headers: { ... } }); async function *streamAsyncIterable(stream) { const reader = stream.getReader(); try { while (true) { const {done, value} = await reader.read(); if (done) { return; } yield value; } } finally { reader.releaseLock(); } } for await(const chunk of streamAsyncIterable(response.body)) { const str = new TextDecoder().decode(chunk, {stream: true}); window.ReactNativeWebView.postMessage(str); } })() `; webviewRef?.current?.injectJavaScript(injectScript); }; const handleMessage = (event: WebViewMessageEvent) => { const data = event.nativeEvent.data; setMessage((prev) => prev + data); }; useEffect(() => { console.log({ message }); }, [message]); return ( <> <WebView ref={webviewRef} source={{ uri: 'YOUR_STREAM_URL' }} style={{ height: 80, width: '100%' }} onMessage={handleMessage} /> <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>{message}</Text> <Button title="Start Streaming" onPress={getStreamData}></Button> </View> </> ); }; export default StreamComponent;
这个链接对我帮助很大:

https://dev.to/hieunh1801/react-native-chatgpt-stream-how-to-5cn

但这部分:

const str = new TextDecoder().decode(chunk);

 - 对我不起作用
我必须这样做:

const str = new TextDecoder().decode(chunk, {stream: true});


此外,当您执行:npm i react-native-webview时,请执行以下操作:npx expo install --fix(无需像其他人提到的那样弹出)

确保您浏览到 YOUR_STREAM_URL 时来自 来源={{ uri: 'YOUR_STREAM_URL' }} 使用您的手机,您可以看到您的 API。本地主机将无法工作,您需要使用您的网络 IP。

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