Skip to content

Commit e6f7a55

Browse files
authored
Merge pull request #30 from int2001/ws_stream
Ws stream
2 parents 1fb941a + 5df4490 commit e6f7a55

3 files changed

Lines changed: 422 additions & 2 deletions

File tree

index.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const path = require("path")
88
const cors = require('cors');
99
const morgan = require('morgan');
1010
const fetch = require('node-fetch'); // Fetch for API requests
11+
const WebSocket = require('ws'); // WebSocket server
1112
var dxcc;
1213

1314
//Load config from file or from environment variables
@@ -40,6 +41,9 @@ app.use(express.json());
4041
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :response-time ms'));
4142
app.use(cors({ origin: '*' }));
4243

44+
// Serve static files (for demo page)
45+
app.use(config.baseUrl + '/demo', express.static(path.join(__dirname, 'public')));
46+
4347
// DXCluster connection and spot cache
4448
let spots=[];
4549

@@ -48,6 +52,32 @@ const bandIndex = new Map(); // Map<band, Set<spot>>
4852
const frequencyIndex = new Map(); // Map<frequency, spot>
4953
const sourceIndex = new Map(); // Map<source, Set<spot>>
5054

55+
// WebSocket clients
56+
const wsClients = new Set();
57+
58+
/**
59+
* Broadcasts a new spot to all connected WebSocket clients
60+
*/
61+
function broadcastSpot(spot) {
62+
if (wsClients.size === 0) return;
63+
64+
const message = JSON.stringify({
65+
type: 'spot',
66+
data: spot
67+
});
68+
69+
wsClients.forEach((client) => {
70+
if (client.readyState === WebSocket.OPEN) {
71+
try {
72+
client.send(message);
73+
} catch (error) {
74+
console.error('Error sending to WebSocket client:', error);
75+
wsClients.delete(client);
76+
}
77+
}
78+
});
79+
}
80+
5181

5282
// -----------------------------------
5383
// Utility Functions
@@ -206,9 +236,29 @@ app.get(config.baseUrl + '/stats', (req, res) => {
206236
*/
207237
async function main() {
208238
try {
209-
app.listen(config.webport, '0.0.0.0', () => {
239+
const server = app.listen(config.webport, '0.0.0.0', () => {
210240
console.log(`Listener started on Port ${config.webport}`);
211241
});
242+
243+
// Create WebSocket server
244+
const wss = new WebSocket.Server({ server });
245+
246+
wss.on('connection', (ws) => {
247+
console.log('New WebSocket client connected');
248+
wsClients.add(ws);
249+
250+
ws.on('close', () => {
251+
console.log('WebSocket client disconnected');
252+
wsClients.delete(ws);
253+
});
254+
255+
ws.on('error', (error) => {
256+
console.error('WebSocket error:', error);
257+
wsClients.delete(ws);
258+
});
259+
});
260+
261+
console.log(`WebSocket server started on Port ${config.webport}`);
212262
reconnect(); // Start the connection to DXCluster
213263
} catch (e) {
214264
console.error("Error starting server:", e);
@@ -279,6 +329,9 @@ async function handlespot(spot, spot_source = "cluster"){
279329
// Update indexes
280330
updateIndexes(dxSpot);
281331

332+
// Broadcast to WebSocket clients
333+
broadcastSpot(dxSpot);
334+
282335
//empty out spots if maximum retainment is reached
283336
if (spots.length>config.maxcache) {
284337
const removed = spots.shift();

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"express": "^4.18.2",
1010
"gearman": "^2.1.0",
1111
"morgan": "^1.10.0",
12-
"net": "^1.0.2"
12+
"net": "^1.0.2",
13+
"ws": "^8.18.3"
1314
},
1415
"devDependencies": {
1516
"@types/bun": "latest"

0 commit comments

Comments
 (0)