I'm developing a project using React/ NextJS + API Route and I need to listen to a queue and display messages on the screen as they arrive. For this I created a Page /pages/client.tsx
and an API pages/api/consumer.ts
.
Through logs that I added to the two files, I can see that the API is correctly consuming the queue because as I produce a new message it is displayed in the NextJS application terminal, however, apparently it does not reach the client.
On the page side, through logs it seems to me that the connection is being established because I added a console log within the onopen
event and it is being printed.
Still in the browser console, I accessed the network tab and found the API call with status 200. When accessing the EventStream tab, which I assume is where received messages should appear, I find an empty table as you can see in the screenshot below:
My API code
import { NextApiRequest, NextApiResponse } from 'next';
import amqp from 'amqplib';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const connection = await amqp.connect('{CONNECTION STRING}');
const channel = await connection.createChannel();
const queue = '{FILA}';
await channel.assertQueue(queue, { durable: true });
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.write(`data: "initial message"\n\n`);
channel.consume(queue, (message) => {
if (message !== null) {
console.log('receive message');
console.log(message.content.toString());
res.write(`data: ${message.content.toString()}\n\n`);
channel.ack(message);
}
});
req.on('close', () => {
console.log('Client closed connection');
channel.close();
connection.close();
});
} catch (error) {
res.status(500).json({ success: false, error: 'Internal server error' });
}
}
My Page Code
import { useEffect, useState } from 'react';
const MyPage = () => {
useEffect(() => {
const eventSource = new EventSource('{API}');
eventSource.onopen = (e) => {
console.log("The connection has been established.");
};
eventSource.onmessage = (event) => {
const newMessage = JSON.parse(event.data);
console.log('receive message');
console.log(event.data);
};
eventSource.onerror = (error) => {
console.log('event error');
eventSource.close();
}
return () => {
eventSource.close();
};
}, []);
return (
);
}
export default MyPage;
I expected that when I received a message in the RabbitMQ queue, it would be consumed in my API/Consumer that I created with the NextJS Route API feature, sent to my client page and displayed on the screen.