- 给定的接口是POST请求,请求时需要携带参数
解决方案:
使用@microsoft/fetch-event-source这个库中的fetchEventSource来发送带请求体的POST请求。示例代码:
import { fetchEventSource } from '@microsoft/fetch-event-source';
const handleSubmit = async () => {
//提交之前将机器人上次回答内容存储到消息列表中
if (text.length > 0) {
setMessages((prevMessages) => [...prevMessages, { sender: 'chatbot', text: text.join('') }]);
setText([]);
}
if (inputValue.length === 0) {
return message.error('请输入您的问题!')
}
setLoading(true);
setMessages((prevMessages) => [...prevMessages, { sender: 'You', text: inputValue }]);
fetchEventSource('/chatapi/chat/chat',
{
method: 'POST',
withCredentials: true,
headers: {
"Content-Type": 'application/json',
},
body: JSON.stringify({
"query": inputValue,
"conversation_id": "",
"history_len": -1,
"history": messages.length > 1 ? messages.slice(-2).map((item) => {
return {
'role': item.sender === 'chatbot' ? 'assistant' : 'user',
'content': item.text
}
}) : [],
"stream": true,
"model_name": "chatglm3-6b",
"temperature": 0.7,
"max_tokens": 0,
"prompt_name": "default"
}),
async onopen(response) {
console.log('open');
},
async onmessage(event) {
// console.log(event.data);
setText(revMessages => [...revMessages, parseJsonWithNumberValidation(event.data).text])
},
onerror(error) {
console.info(error);
setSysMsg(error)
},
onclose() {
console.log('close');
setInputValue('');
setLoading(false);
}
}
)
};
参考:https://www.cnblogs.com/HTLucky/p/17326459.html
- 直接请求服务接口能够正常流式响应,中间经过1层或多层代理之后,无法流式响应,而是一次性将响应结果给到前端。
解决方案:
配置nginx代理,支持SSE
http {
...
server {
...
location /sse {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# SSE 连接时的超时时间
proxy_read_timeout 86400s;
# 取消缓冲
proxy_buffering off;
# 关闭代理缓存
proxy_cache off;
# 禁用分块传输编码
chunked_transfer_encoding on;
# 反向代理到 SSE 应用的地址和端口
proxy_pass http://backend-server;
}
...
}
...
}
- 如果中间经过了N层代理,有WAF或者CDN这些时,将所有代理的请求头添加上
X-Accel-Buffering 这个参数值是no。我的理解是只有请求真实接口的那一层代理不用加这个参数,前面的N-1层代理都需要添加上这个参数。
location /path {
...
add_header X-Accel-Buffering "no";
...
}
问题类型如同:https://github.com/chatchat-space/Langchain-Chatchat/issues/1712
参考:解决SSE流被Nginx缓存的问题_nginx sse-CSDN博客
- 关于X-Accel-Buffering参数的解释:
`X-Accel-Buffering` 是一个特殊的请求头参数,用于控制反向代理服务器(如Nginx)与后端服务器之间的数据缓冲行为。
当客户端发送请求到反向代理服务器时,反向代理服务器会将请求转发至后端服务器处理,并将后端服务器返回的响应传递给客户端。在这个过程中,反向代理服务器可以选择是否缓冲响应数据。
`X-Accel-Buffering` 请求头参数用于向反向代理服务器传递缓冲设置指令,具体含义如下:
- 如果 `X-Accel-Buffering` 的值为 "yes",表示反向代理服务器应该启用缓冲,将响应数据完全接收后再传递给客户端。这样可以提高性能,特别是对于大型响应或响应时间较长的情况。
- 如果 `X-Accel-Buffering` 的值为 "no",表示反向代理服务器应禁用缓冲,即实时将后端服务器返回的数据传递给客户端。这对于实时性要求较高的应用场景可能更为合适。
需要注意的是,`X-Accel-Buffering` 请求头参数的作用需要在反向代理服务器的配置中进行解释和生效。例如,在 Nginx 中,可以通过配置 `proxy_buffering` 指令来控制缓冲行为,并根据 `X-Accel-Buffering` 的值进行相应的设置。
总结起来,`X-Accel-Buffering` 请求头参数用于指示反向代理服务器是否缓冲响应数据,提供更好的性能或实时性,具体行为取决于反向代理服务器的配置和实现。