我正在尝试在 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 的限制,我应该放弃这个吗?
我设法让它像这样工作:
...
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});
确保您浏览到 YOUR_STREAM_URL 时来自 来源={{ uri: 'YOUR_STREAM_URL' }} 使用您的手机,您可以看到您的 API。本地主机将无法工作,您需要使用您的网络 IP。