Fix missing headers in SSE queries

This commit is contained in:
Ian Renton
2026-08-14 23:47:22 +01:00
parent efec8e220e
commit ef2c23c8b6
16 changed files with 358 additions and 129 deletions
+49 -38
View File
@@ -9,8 +9,7 @@ const ITU_ZONES_COLOR_DARK = 'rgba(120, 120, 60, 1.0)';
const WAB_WAI_GRID_COLOR_DARK = 'rgba(60, 60, 120, 1.0)';
// SSE connection for live spot updates
let evtSource;
let restartSSEOnErrorTimeoutId;
let sseAbortController = null;
// Map dx_call to a pair of marker & geodesic line, so we can de-duplicate spots as they arrive and only show
// one marker per dx_call. The key here is actually dx_call + SSID if the spot gives us an SSID; this is mostly for
// if APRS spots are enabled so we can ID a home and mobile station separately rather than our marker oscillating
@@ -35,8 +34,8 @@ let firstLoad = true;
// Load spots and populate the map.
function loadSpots() {
// Close any existing SSE connection before fetching fresh data
if (evtSource != null) {
evtSource.close();
if (sseAbortController != null) {
sseAbortController.abort();
}
// Including QRZ/HamQTH lookups to improve positions causes the load to be really slow, so on first load
// the user would be waiting ages without data and will think it's broken. We therefore load in several
@@ -45,7 +44,8 @@ function loadSpots() {
// 2) (If we have credentials) reload with them, replacing what's already there,
// 3) Subscribe to the SSE endpoint (with credentials if we have them) so that updates come with augmented
// data if they can.
$.ajax({url: '/api/v2/spots' + buildQueryString(), dataType: 'json', headers: getCredentialHeaders(), success: function (jsonData) {
$.ajax({
url: '/api/v2/spots' + buildQueryString(), dataType: 'json', success: function (jsonData) {
// Store data
spots = jsonData;
// Update map
@@ -54,14 +54,19 @@ function loadSpots() {
terminator.setTime();
}
// Check if we have any credentials to use
if (getCredentialQueryString() !== "") {
if (Object.keys(getCredentialHeaders()).length > 0) {
// OK, we have credentials and have loaded once without them so the user has a basic map. Now reload
// with the credentials and replace what's on the map, so we can improve the data.
$.getJSON('/api/v1/spots' + buildQueryString(true), function (jsonData2) {
spots = jsonData2;
updateMap();
// Now start the ongoing SSE connection
startSSEConnection();
$.ajax({
url: '/api/v2/spots' + buildQueryString(),
dataType: 'json',
headers: getCredentialHeaders(),
success: function(jsonData2) {
spots = jsonData2;
updateMap();
// Now start the ongoing SSE connection
startSSEConnection();
}
});
} else {
// We had no credentials with which to augment the data anyway, so just start the SSE connection
@@ -73,37 +78,43 @@ function loadSpots() {
// Start the SSE connection to receive new spots as they arrive
function startSSEConnection() {
if (evtSource != null) {
evtSource.close();
if (sseAbortController != null) {
sseAbortController.abort();
}
sseAbortController = new AbortController();
// SSE is going to fetch only a few spots at a time, so now we include QRZ/HamQTH credentials because the delay won't be significant.
evtSource = new EventSource('/api/v1/spots/stream' + buildQueryString(true));
fetchEventSource('/api/v2/spots/stream' + buildQueryString(), {
headers: getCredentialHeaders(),
signal: sseAbortController.signal,
openWhenHidden: true,
evtSource.onmessage = function (event) {
const newSpot = JSON.parse(event.data);
const key = spotKey(newSpot);
onmessage(event) {
if (!event.data) {
return; // heartbeat/keep-alive, nothing to do
}
// Remove existing marker/geodesic for this callsign if present
removeSpotFromMap(key);
spots = spots.filter(s => spotKey(s) !== key);
const newSpot = JSON.parse(event.data);
const key = spotKey(newSpot);
// Skip spots with no map coordinates
if (newSpot["dx_latitude"] == null || newSpot["dx_longitude"] == null) {
return;
// Remove existing marker/geodesic for this callsign if present
removeSpotFromMap(key);
spots = spots.filter(s => spotKey(s) !== key);
// Skip spots with no map coordinates
if (newSpot["dx_latitude"] == null || newSpot["dx_longitude"] == null) {
return;
}
// Add to data store and map
spots.unshift(newSpot);
addSpotToMap(newSpot);
},
onerror(err) {
console.error('SSE error:', err);
return 1000;
}
// Add to data store and map
spots.unshift(newSpot);
addSpotToMap(newSpot);
};
evtSource.onerror = function () {
if (evtSource != null) {
evtSource.close();
}
clearTimeout(restartSSEOnErrorTimeoutId);
restartSSEOnErrorTimeoutId = setTimeout(startSSEConnection, 1000);
};
});
}
// Remove spots from the map that are older than the selected max age.
@@ -603,8 +614,8 @@ function displayIntroBox() {
$(document).ready(function () {
// Close SSE connection cleanly when navigating away
window.addEventListener('beforeunload', function () {
if (evtSource != null) {
evtSource.close();
if (sseAbortController != null) {
sseAbortController.abort();
}
});