node.js - React EventSource 有時無法從 NodeJs 後端獲取資料
我正在使用一個 React 組件從伺服器獲取即時資料。我使用 EventSource 並監聽我的伺服器端點。我接收到資料的頻率是……80%。從後端我從 MongoDB 收到的資料是 100%,但當我將它們發送到前端時,我並不總是能收到它們。
我在瀏覽器的控制台或網路標籤中沒有錯誤。
伺服器:
export const realTimeLogs = async (req: Request, res: Response) => {
res.writeHead(200, {
Connection: 'keep-alive',
'Keep-Alive': 'timeout=3600, max=10',
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Transfer-Encoding': 'chunked',
'Access-Control-Allow-Origin': 'http://localhost:3000',
'Access-Control-Allow-Credentials': 'true',
'X-Accel-Buffering': 'no',
});
res.write(''); //Without this, the EventSource.open event would not get triggered.
writeStream(res);
}
const writeStream = async (res: Response) => {
const msg: ReceiveMessageCommandOutput = await createAndReceiveMessage(
'mySQSQueue'
); //Get data from SQS
if (msg.Messages) {
const msgBody: string | undefined = msg.Messages[0].Body;
console.log(`${msgBody}`); //The server gets 100% of the messagges, I see it here.
const receiptHandle: string | undefined = msg.Messages[0].ReceiptHandle;
setTimeout(() => {
res.write('retry: 10000\n', 'utf-8');
res.write(`id: ${JSON.parse(msgBody!).payload._id}\n`, 'utf-8');
res.write('event: message\n');
res.write(`data: ${msgBody}\n\n`, 'utf-8'); //THIS IS HOW REACT CLIENT SHOULD GET DATA
}, 0);
if (receiptHandle)
await createAndDeleteMessage('mySQSQueue', receiptHandle);
}
let timeout = setTimeout(() => {
clearTimeout(timeout);
return writeStream(res); //Re-call this function as infinite loop.
}, 5000);
};
當 React 客戶端:
useEffect(() => {
console.log('RE-RENDER');
const source = new EventSource(
`${BASE_URL}/${ROOT_ENDPOINTS.MANAGER}/${MANAGER_ENDPOINTS.GETREALTIMELOGS}`,
{
withCredentials: true,
}
);
source.onopen = (event: Event) => {
console.log('OnOpen: ', event);
};
source.onerror = (event: Event) => {
console.error('Errore: ', event);
};
source.onmessage = (event: MessageEvent) => {
let payload: MSGManager;
try {
payload = JSON.parse(event.data);
eventSourceHandler(payload);
} catch (e) {
console.error('errore: ', e);
}
};
setEventSource(source);
return () => {
console.log('CLEANUP');
eventSource?.close();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
我能毫無問題地獲取即時數據,唯一的問題是並非所有數據都傳送到客戶端。例如,6/10 條消息能正確接收,有時是 1/15,這非常隨機。控制台沒有錯誤,連線也始終保持活躍。我在網上找不到任何解決方案。
編輯:看起來我只需要那一行 res.write("data: myData\n\n") 來使用 onmessage() 監聽器。否則,如果在資料之前有其他東西,監聽器似乎不會總是收到訊息。現在,如果我刷新頁面,會遇到同樣的問題,但如果我同時重置伺服器和頁面,它仍然能正常運作並收到 100% 的訊息。