-
Notifications
You must be signed in to change notification settings - Fork 0
/
serverSideEvents.js
106 lines (82 loc) · 2.82 KB
/
serverSideEvents.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* eslint-disable no-await-in-loop */
import fetch from 'node-fetch';
let clients = [];
let isSendingCryptoUpdates = false;
const retrieveCryptoPrices = async () => {
const cryptoToFetch = [
'bitcoin',
'ethereum',
'swissborg',
'tether',
'cardano',
];
const fiatCurrenciesToMatch = [
'usd',
];
const cryptoURI = encodeURIComponent(cryptoToFetch.join());
const vsCurrenciesURI = encodeURIComponent(fiatCurrenciesToMatch.join());
const cryptoAPI = `https://api.coingecko.com/api/v3/simple/price?ids=${cryptoURI}&vs_currencies=${vsCurrenciesURI}`;
const cryptoPrices = {
bitcoin: 0,
ethereum: 0,
swissborg: 0,
tether: 0,
cardano: 0,
};
try {
const response = await fetch(cryptoAPI);
if (response.ok) {
const data = await response.json();
cryptoPrices.bitcoin = data.bitcoin.usd;
cryptoPrices.ethereum = data.ethereum.usd;
cryptoPrices.swissborg = data.swissborg.usd;
cryptoPrices.tether = data.tether.usd;
cryptoPrices.cardano = data.cardano.usd;
}
} catch (err) {
console.log(err);
}
return cryptoPrices;
};
const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
const sendCryptoUpdates = async (delay) => {
while (clients.length > 0) {
isSendingCryptoUpdates = true;
// Retrieve crypto prices
const cryptoPrices = await retrieveCryptoPrices();
// Send data to every connected client
clients.forEach((client) => client.response.write(`data: ${JSON.stringify(cryptoPrices)}\n\n`));
await timeout(delay);
}
isSendingCryptoUpdates = false;
};
const register = (request, response) => {
const headers = {
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
};
response.writeHead(200, headers);
const newClient = {
id: Date.now(),
response,
};
console.log(`Client ${newClient.id} : new client connected`);
clients.push(newClient);
request.on('close', () => {
console.log(`Client ${newClient.id} : connection closed`);
clients = clients.filter((client) => client.id !== newClient.id);
});
/*
Before calling sendCryptoUpdates(), we check if it is not already sending updates to clients.
This check allows not to run sendCryptoUpdates() indefinitely just to check if there is a
client that is listening on crypto updates.
The sendCryptoUpdates() function will be called and will loop only when at least one client
is connected.
*/
if (!isSendingCryptoUpdates) {
const delay = 10000;
sendCryptoUpdates(delay);
}
};
export default { register };