I have a server that emits data at regular intervals. I want to use this data in my rest API, how do I fetch it? It needs to be automatically called when the data is pushed from the external source. I have tried the following code but it did not work.
var EventSource = require("eventsource");
var url = "..." // Source URL
var es = new EventSource(url);
es.onmessage = (event) => {
console.log(event)
const parsedData = JSON.parse(event.data);
console.log(parsedData)
}
I have a server that emits data at regular intervals. I want to use this data in my rest API, how do I fetch it? It needs to be automatically called when the data is pushed from the external source. I have tried the following code but it did not work.
var EventSource = require("eventsource");
var url = "..." // Source URL
var es = new EventSource(url);
es.onmessage = (event) => {
console.log(event)
const parsedData = JSON.parse(event.data);
console.log(parsedData)
}
Share
Improve this question
edited Oct 9, 2020 at 18:50
Sarun UK
6,7667 gold badges26 silver badges50 bronze badges
asked Oct 2, 2020 at 3:33
KowshhalKowshhal
2915 silver badges15 bronze badges
4
- Why do you want to use the data in REST API? REST API and SSE are different approaches. REST API is initiated by the client side and client waits for the response, and its different from the SSE. – IRSHAD Commented Oct 4, 2020 at 19:09
- I have an external source which supplies me data regularly, I need to extract the data, make some modifications and store it into a database. That’s the reason I want to use it in my backend rest server. – Kowshhal Commented Oct 5, 2020 at 18:05
- When that external source push the data, you have to listen for it by subscribing to its events and save it to the database (or you could also consider writing a webhook for the same). Thus, whenever you call your REST API next time, you will be able to fetch the latest data from the database. – IRSHAD Commented Oct 6, 2020 at 0:46
- Can you provide a code sample ? I tried it but it’s doesn’t work. Check the code which I tried above. – Kowshhal Commented Oct 6, 2020 at 4:23
3 Answers
Reset to default 3I had the same problem when I wanted to consume the SSE from a different microservice , I followed this approach and it worked for me.
node.js file
const eventSource = require('eventsource');
async socEventStream(req, res) {
// list of the event you want to consume
const list = ['EVENT1_NAME', 'EVENT2_NAME','EVENT3_NAME'];
try {
const e = new eventSource('url//of_sse_event', {});
for (const l of list) {
e.addEventListener(l, (e) => {
const data = e.data;
// Your data
console.log('event data =====>',data)
});
};
res.on('close', () => {
for (const l of list) {
e.removeEventListener(l, (e) => {
});
}
})
} catch (err) {
console.log(err)
}
}
if you want to consume event on node.js and send it to client then
const eventSource = require('eventsource');
async socEventStream(req, res) {
// setting express timeout for more 24 hrs
req.setTimeout(24 * 60 * 60 * 1000);
// setting headers for client to send consumed sse to client
const headers = {
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe,x-access-key',
'Access-Control-Allow-Methods': 'POST, PUT, GET, OPTIONS, DELETE',
'Access-Control-Allow-Origin': '*',
};
res.setTimeout(24 * 60 * 60 * 1000);
res.writeHead(200, headers);
// list of the event you want to consume
const list = ['EVENT1_NAME', 'EVENT2_NAME','EVENT3_NAME'];
try {
const e = new eventSource('url//of_sse_event', {});
for (const l of list) {
e.addEventListener(l, (e) => {
const data = e.data;
// Your data
res.write(`event:${l}\ndata:${data}\n\n`);
});
};
req.on('close', () => {
for (const l of list) {
e.removeEventListener(l, (e) => {
});
}
})
} catch (err) {
console.log(err)
}
}
For testing purposes set up something like this on the server. Create a stream with and event name so you can listen for it on the client.
const SseStream = require('ssestream')
app.get('/sse', (req, res) => {
console.log('new connection')
const sseStream = new SseStream(req)
sseStream.pipe(res)
const pusher = setInterval(() => {
sseStream.write({
event: 'server-time',
data: new Date().toTimeString()
})
}, 1000)
res.on('close', () => {
console.log('lost connection')
clearInterval(pusher)
sseStream.unpipe(res)
})
})
And on the client you listen for the event like this
var EventSource = require('eventsource')
var es = new EventSource(url)
es.addEventListener('message', function (e) {
console.log(e.data)
})
may try this package @llm-eaf/node-event-source
// this.res is Express Response
await nodeEventSource(`https://api.openai./v1${url}`, {
method: method,
headers: {
Authorization: "************",
"Content-Type": "application/json",
},
data: this.req.body,
onOpen: () => {
this.res.type(EventStreamContentType);
},
onMessage: (ev) => {
this.res.write(`data: ${ev.data}\n\n`);
// do something with the message
},
});
this.res.end();