1. Problema
Quando Discourse è configurato con una CDN, si verifica un errore comune:
/message-bus/204234de907442e8b77e153786a58e5b/poll
Connessione fallita / timeout / codice di stato anomalo
Impatto:
-
Notifiche fallite: Il punto rosso (nuovo PM/risposta) non appare più in tempo reale; gli aggiornamenti potrebbero arrivare in ritardo o non arrivare affatto.
-
Aggiornamenti in tempo reale interrotti: Nuovi post/like/voti non si aggiornano automaticamente; è necessario un aggiornamento manuale della pagina.
-
Esperienza utente degradata: Appaiono messaggi di “Connessione persa”; le interazioni sono lente.
-
Aumento del carico del server: Il frontend continua a ritentare i sondaggi, aumentando la pressione sull’origine.
Motivo: Discourse utilizza il long polling per mantenere la comunicazione in tempo reale. Molte CDN applicano la memorizzazione nella cache predefinita, timeout abbreviati, controlli di sfida/firewall o buffering su connessioni lunghe, causando interruzioni o risposte memorizzate nella cache che interrompono il comportamento in tempo reale.
2. Approccio Generale (Stabilità Prima di Tutto)
-
Separazione dei domini: Instrada MessageBus attraverso un dominio dedicato che si connette direttamente all’origine.
- Dominio del forum (tramite CDN): https://bbs.example.com
- Dominio MessageBus (senza CDN): https://messagebus.example.com
-
Livello di reverse proxy (Nginx):
- Abilita CORS per /message-bus.
- Disabilita il buffering del proxy, rilassa i timeout, vieta esplicitamente la memorizzazione nella cache.
-
Livello CDN (se ancora utilizzato):
- Configura /message-bus/* con nessuna memorizzazione nella cache, timeout esteso, nessuna sfida JS/CAPTCHA/rate limiting e passaggio di cookie/autorizzazione.
- Oppure bypassa completamente la CDN.
3. Passaggi di Implementazione
1) Configura le Variabili d’Ambiente di Discourse
Modifica app.yml (solitamente in /var/discourse/containers/app.yml) e aggiungi/modifica sotto env::
env:
DISCOURSE_MESSAGE_BUS_REDIS_ENABLED: true
DISCOURSE_LONG_POLLING_BASE_URL: "https://messagebus.example.com"
Applica le modifiche (distribuzione ufficiale):
cd /var/discourse
./launcher rebuild app
Spiegazione:
- DISCOURSE_LONG_POLLING_BASE_URL indica al frontend di utilizzare il dominio MessageBus.
- REDIS_ENABLED dovrebbe rimanere abilitato.
2) DNS e Certificato
- Punta messagebus.example.com direttamente all’origine, bypassando la CDN (best practice).
- Imposta un certificato HTTPS valido per il dominio.
3) Nginx (Dominio MessageBus) Reverse Proxy e CORS
Aggiungi o aggiorna quanto segue nel blocco server per messagebus.example.com:
location ^~ /message-bus {
# (1) Gestisci il preflight CORS (OPTIONS)
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;
add_header 'Access-Control-Max-Age' 1728000 always;
add_header 'Content-Type' 'text/plain; charset=UTF-8' always;
add_header 'Content-Length' 0 always;
return 204;
}
# (2) Reverse proxy a Discourse
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
# o, se standalone:
# proxy_pass http://127.0.0.1:3000;
# (3) Impedisci intestazioni CORS duplicate
proxy_hide_header Access-Control-Allow-Origin;
proxy_hide_header Access-Control-Allow-Credentials;
proxy_hide_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
proxy_hide_header Access-Control-Max-Age;
# (4) CORS normale per le richieste
add_header 'Access-Control-Allow-Origin' 'https://bbs.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,discourse-deferred-track-view-topic-id,discourse-present,discourse-track-view,discourse-deferred-track-view,x-silence-logger,dont-chunk,x-shared-session-key' always;
# (5) Impostazioni di stabilità per il long polling
proxy_read_timeout 120s;
proxy_send_timeout 120s;
proxy_connect_timeout 60s;
proxy_buffering off;
add_header X-Accel-Buffering no always;
# (6) Vieta esplicitamente la memorizzazione nella cache
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}
Nota di sicurezza: Se viene utilizzato Access-Control-Allow-Credentials: true, Origin non deve essere *; deve corrispondere al dominio esatto del forum.
4) Regole CDN (se il forum è ancora dietro CDN)
Consigliato: imposta nessuna cache + timeout esteso + bypass WAF/rate limiting per questi percorsi:
Esempio di espressione regolare:
^/(session|login|message-bus|admin|u|users)(/|$)
Politica:
- Nessuna memorizzazione nella cache del browser/nodo (no-store/no-cache).
- Timeout upstream/lettura/idle ≥ 60–120s.
- Disabilita sfide JS/CAPTCHA/gestione bot.
- Passa attraverso cookie e intestazioni di autorizzazione (non rimuovere).
4. Come Verificare il Successo
1) Strumenti per Sviluppatori del Browser → Rete
Nella pagina del forum:
- Osserva /message-bus/…/poll.
- La richiesta dovrebbe “bloccarsi” per circa 20–60 secondi, quindi restituire 200 (possibilmente vuoto).
- La richiesta di sondaggio successiva viene attivata automaticamente.
Controlla le intestazioni di risposta:
- Access-Control-Allow-Origin: https://bbs.example.com
- Cache-Control: no-store
- Nessun Age, X-Cache: HIT o CF-Cache-Status: HIT (significa che non è memorizzato nella cache).
Problemi comuni:
- Errori fissi di 10s/30s → timeout del margine/origine.
- 504/524: timeout.
- 499: disconnessione del livello intermedio.
- 403/401: blocco WAF/autenticazione.
2) Sonda Rapida da Riga di Comando (opzionale)
Verifica la connettività e le intestazioni (non il polling completo):
curl -I "https://messagebus.example.com/message-bus/health-check" \
-H "Origin: https://bbs.example.com"
Nota: i sondaggi effettivi richiedono il contesto della sessione; questo verifica solo CORS e la connettività.