Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ services:
DXPORT: 8000 # Port of DXCluster upstream
DXCALL: [my_call] # Login-Call for Cluster
DXPASSWORD: [my_password] # Login-Passwort for Cluster (in most of all cases leave this blank!!
# If CLUSTERS is filled / present, it overrides the above DX-Parameters. The "cluster"-parameter is optional. if not set, or set to the same value, the last spot will be taken. if different: multiple spots on same QRG are displayed. Please check carefully the JSON-Syntax here!
CLUSTERS: '[{ "host": "dxfun.com", "port": 8000, "call":"[mycall]", "loginPrompt": "login", "cluster":"DXCluster" }, { "host": "cluster.sota.org.uk", "port": 7300, "call":"[mycall]", "loginPrompt": "login","cluster":"DXCluster" }]'
POTA_INTEGRATION: false # wether to poll POTA for spots
POTA_POLLING_INTERVAL: 120 # polling interval for POTA in seconds
ports:
Expand Down
99 changes: 60 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,20 @@ if (process.env.WEBPORT === undefined) {
config = require("./config.js");
} else {
config={maxcache: process.env.MAXCACHE, webport: process.env.WEBPORT, baseUrl: process.env.WEBURL, dxcc_lookup_wavelog_url: process.env.WAVELOG_URL, dxcc_lookup_wavelog_key: process.env.WAVELOG_KEY, includepotaspots: process.env.POTA_INTEGRATION, potapollinterval: process.env.POTA_POLLING_INTERVAL };
config.dxc={ host: process.env.DXHOST, port: process.env.DXPORT, loginPrompt: 'login:', call: process.env.DXCALL, password: process.env.DXPASSWORD };
config.clusters=JSON.parse(process.env.CLUSTERS || '[]');
config.dxc={ host: process.env.DXHOST, port: process.env.DXPORT, loginPrompt: 'login:', call: process.env.DXCALL, password: process.env.DXPASSWORD };
}

let clusters = [];
if (config.clusters.length>0) {
// New format: host:port,host:port,host:port
clusters = config.clusters;
} else {
// Old format: single cluster via CLUSTER_HOST/CLUSTER_PORT
clusters[0] = config.dxc;
}


morgan.token('remote-addr', function (req, res) {
var ffHeaderValue = req.headers['x-forwarded-for'];
return ffHeaderValue || req.connection.remoteAddress;
Expand All @@ -30,9 +41,9 @@ app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:htt
app.use(cors({ origin: '*' }));

// DXCluster connection and spot cache
let conn = new DXCluster()
let spots=[];


// -----------------------------------
// Utility Functions
// -----------------------------------
Expand Down Expand Up @@ -82,45 +93,55 @@ function toUcWord(string) {
/**
* Initiates a connection to the DXCluster and logs events.
*/
function reconnect() {
logConnectionState('attempting', config.dxc, 'DXCluster server for receiving spots');
conn.connect(config.dxc)
.then(() => {
logConnectionState('connected', config.dxc, 'DXCluster server for receiving spots');
})
.catch((err) => {
logConnectionState('failed', config.dxc, 'DXCluster server for receiving spots', err);
setTimeout(reconnect, 5000); // Retry connection after 5 seconds
});
}

// Event listeners for connection status changes
conn.on('close', () => {
logConnectionState('closed', config.dxc, 'DXCluster server connection closed');
reconnect();
});

conn.on('timeout', () => {
logConnectionState('timeout', config.dxc, 'DXCluster server connection timed out');
reconnect();
});

conn.on('error', (err) => {
logConnectionState('error', config.dxc, 'DXCluster server connection error', err);
reconnect();
});

// -----------------------------------
// DXCluster Spot Handling
// -----------------------------------

/**
* Processes spots received from DXCluster.
*/
conn.on('spot', async function x(spot) {
await handlespot(spot, "cluster");
})
function reconnect() {
function conn_one(cluster) {
logConnectionState('attempting', cluster.host, 'DXCluster server for receiving spots');
const conn = new DXCluster();
try {
conn.connect(cluster).then(() => {
logConnectionState('connected', cluster.host, 'DXCluster server for receiving spots');
})
.catch((err) => {
logConnectionState('failed', cluster.host, 'DXCluster server for receiving spots', err);
conn_one(cluster);
});

// Event listeners for connection status changes
conn.on('close', () => {
logConnectionState('closed', cluster.host, 'DXCluster server connection closed');
conn_one(cluster);
});

conn.on('timeout', () => {
logConnectionState('timeout', cluster.host, 'DXCluster server connection timed out');
conn_one(cluster);
});

conn.on('error', (err) => {
logConnectionState('error', cluster.host, 'DXCluster server connection error', err);
conn_one(cluster);
});
// -----------------------------------
// DXCluster Spot Handling
// -----------------------------------

/**
* Processes spots received from DXCluster.
*/
conn.on('spot', async function x(spot) {
await handlespot(spot, (cluster.cluster || 'cluster'));
});
} catch (e) {
logConnectionState('error', config.host, 'DXCluster not reachable ');
console.log(e);
}
}

clusters.forEach(cluster => {
conn_one(cluster);
});
}
// -----------------------------------
// API Endpoints
// -----------------------------------
Expand Down