javascript - EventSource recebe todos os pedaços de uma vez ao transmitir via Nextjs API Routes
Problema
Estou tentando transmitir dados para meu React Frontend via EventSources, o que meio que funciona. O problema é que recebo todos os pedaços de dados de uma vez em vez de um após o outro. O que meio que derrota o propósito do método, já que agora é basicamente uma requisição GET.
Código
Estou usando as rotas de API do Next.js e este é o meu código nesta rota:
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
answerStream.data
.on("data", (chunk: string) => res.write(chunk))
.on("error", (error: Error) => {
console.error(error);
res.end();
})
.on("end", () => res.end());
Este é o código no Frontend:
const eventSource = new EventSource(url);
eventSource.addEventListener("message", e => {
try {
if (e.data == "[DONE]") eventSource.close();
else {
const messageObject = JSON.parse(e.data);
setArticle(state => (state += messageObject?.choices[0]?.text));
}
} catch (error) {
console.log(error);
}
});
eventSource.addEventListener("close", e => {
console.log("Connection closed with the server");
setSubmitting(false);
});
eventSource.addEventListener("error", e => {
setError(e?.message || "Leider ist ein Fehler aufgetreten");
setSubmitting(false);
eventSource.close();
});
Informações
Há algo de errado na minha implementação? Ou o Next.js tem um comportamento estranho com EventSource?
Resposta #1
Solução
Ok, eu encontrei a solução nesta discussão do Github:
Parece que o problema é que o middleware adiciona uma codificação gzip que o navegador negociou usando o cabeçalho
Para corrigir isso, é necessário sobrescrever esse comportamento adicionando 'Content-Encoding': 'none' aos cabeçalhos no servidor:
res.writeHead(200, {
Connection: 'keep-alive',
'Content-Encoding': 'none',
'Cache-Control': 'no-cache',
'Content-Type': 'text/event-stream',
});
Alternativamente, alguém poderia usar um server.js personalizado.
Resposta #2
siimmmm, isso é o que eu estava procurando, tinha algo parecido, passei cerca de 2 dias de frustração tentando descobrir. aqui está o que acabei fazendo/tendo além disso, havia um cabeçalho de bloco com o qual eu estava experimentando:
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
res.setHeader("Transfer-Encoding", "chunked");
res.setHeader("Content-Encoding", "none");
