据我了解: 使用可读流 MDN
我应该能够使用
Fetch API
将结果从服务器发送到客户端并获得 response.body
,即:
fetch(...).then((response) => response.body);
在我的具体设置中,我的目标是使用
Node
和 Express
从 OpenAI API 获取流式文本响应,以便我可以 在客户端逐块处理文本!.
这里的关键问题是 React Native 无法正确支持
ReadableStream
,因此使用 response.body
时的 fetch
是 undefined
:
这篇文章特别清晰且有帮助,但它没有解决问题,因为它没有使用 RN: https://writer.sh/posts/real-time-openai-response-streaming-node-js/
服务器端示例:
app.post("/gptText", async (req, res) => {
try {
const requestBody = {
model: "gpt-4",
messages: [
{
role: "user",
content: "Say 'hi'",
},
],
stream: true,
};
const completion = await openai.chat.completions.create(requestBody);
res.setHeader("Content-Type", "text/plain");
res.setHeader("Transfer-Encoding", "chunked");
for await (const chunk of completion) {
const [choice] = chunk.choices;
const { content } = choice.delta;
if (content !== undefined) {
console.log(content);
res.write(content);
}
}
res.end();} catch (error) {
console.error("Error: ", error);
res.status(500).json({ error });
}
});
服务器代码运行良好,产生以下输出:
Hi
!
How
can
I
assist
you
today
?
但是当尝试在客户端粘贴/读取响应时,例如:
const response = await fetch(...).then((response) => response.body)...
response.body
是 undefined
而不是 ReadableStream
对象,
当然,以下所需的const reader = response.body.getReader();
也失败了。
重要的是要注意,如果我不使用流,而是只是将整个结果作为单个句子发送,我可以使用
response.text()
来获取它。
我尝试了多种方法,例如使用
RN-fetch-blob
库或 react-native-fetch-api
来尝试使用这些建议的 polyfills
来解决 React Native 中的流式响应,但它们都失败或产生相同的结果。
我也尝试过这样的答案,例如: 如何使用openai api在React Native中实现文本流?
这似乎是最接近解决方案的一个,但这根本不起作用,在实现帖子的方法时,
body
仍然未定义..
很高兴知道我在这里哪里出错了,或者是否有人已经针对这个特定示例完成了解决方法。
谢谢:)
我认为你需要使用 webSocket:
useEffect(() => {
// WebSocket Connection Setup
const socket = new WebSocket('wss://blahblah/aws.com/production/');
socket.onopen = () => console.log('WebSocket Connected');
socket.onmessage = handleMessage;
setWebSocket(socket);
return () => {
if (socket) {
socket.close();
}
};
}, []);
const handleMessage = (事件) => { const data = JSON.parse(event.data);
// Handle incoming messages from WebSocket
if (data.content || data.endOfStream) { // show stream stuff from here useEffect(() => {
// WebSocket Connection Setup
const socket = new WebSocket('wss://blahblah/aws.com/production/');
socket.onopen = () => console.log('WebSocket Connected');
socket.onmessage = handleMessage;
setWebSocket(socket);
return () => {
if (socket) {
socket.close();
}
};
}, []);
const handleMessage = (事件) => { const data = JSON.parse(event.data);
// Handle incoming messages from WebSocket
if (data.content || data.endOfStream) {
} }