Un'integrazione SMPP robusta è questione di disciplina operativa, non solo di PDU corrette: scegliete la modalità di bind giusta, gestite con cura sequence_number e finestra, riprovate con backoff e jitter, rendete idempotente l'invio per evitare doppia fatturazione, riscontrate ogni deliver_sm e riconnettetevi in modo pulito in caso di guasto. Fatto questo, i dettagli del protocollo si sistemano da soli.
bind_transceiverAprire e autenticare la sessionebind_transceiver_respSessione accettatasubmit_smInviare un messaggiosubmit_sm_respAccettato, ID messaggio restituitodeliver_smRicevuta di consegna o messaggio in entratadeliver_sm_respConfermatoenquire_linkKeepalive durante l'inattività
Strategia di bind
Preferite un bind transceiver dove il provider lo consente, così un'unica connessione trasporta submit e ricezione e semplifica la correlazione dei DLR. Concordate per iscritto con il provider il numero di bind simultanei e il TPS per bind prima di scalare. Verificate la versione SMPP negoziata dal bind_resp e gestite esplicitamente i fallimenti di bind — riprovate gli stati transitori in stile ESME_RALYBND, ma trattate ESME_RINVPASWD/ESME_RINVSYSID come errori di configurazione fatali anziché ripetere in loop.
sequence_number e la finestra
Assegnate un sequence_number monotonicamente crescente (da 1 a 0x7FFFFFFF, poi wrap) e usatelo per correlare ogni risposta alla sua richiesta. Tenete traccia delle richieste in sospeso in una mappa indicizzata per sequence_number con un timeout, così una risposta che non arriva mai viene rilevata. Rispettate la finestra: limitate le PDU non riscontrate in volo e sospendete i submit quando è piena anziché inviare alla cieca, cosa che innesca il throttling.
| Stato | Perché |
|---|---|
| Mappa delle richieste in sospeso (per sequence_number) | Correlare le risposte, rilevare i timeout |
| Contatore di occupazione della finestra | Backpressure prima di ESME_RTHROTTLED |
| Chiave di idempotenza per messaggio logico | Impedire l'invio di duplicati in caso di nuovo tentativo |
| Stato del bind + ora dell'ultimo enquire_link_resp | Rileva sessioni inattive |
Retry, backoff e idempotenza
Riprovate i guasti transitori (ESME_RMSGQFUL, ESME_RTHROTTLED, errori di sistema, timeout) con backoff esponenziale e jitter affinché le tempeste di riconnessione non si sincronizzino tra i worker. Non riprovate gli errori permanenti (indirizzo non valido, password non valida). Fondamentale: rendete idempotente l'invio — allegate un vostro riferimento (ad esempio tramite user_message_reference) e deduplicate, così un retry dopo un timeout ambiguo non causi doppia fatturazione o doppia consegna.
Gestione delle ricevute di consegna
Richiedete registered_delivery solo dove utilizzate le ricevute. Rispondete sempre prontamente con deliver_sm_resp ed elaborate in modo asincrono. Correlate le ricevute sul TLV receipted_message_id, normalizzando i formati id esadecimale/decimale, e chiudete un messaggio solo su uno stat finale. Mappate i codici err di rete su una tassonomia normalizzata affinché la qualità sia comparabile tra le rotte. Trattate le notifiche intermedie separatamente dagli stati terminali.
Keepalive e riconnessione
Inviate enquire_link su un timer di inattività e trattate una risposta mancante come sessione morta. A ogni disconnessione, riconnettetevi con backoff e jitter anziché ripetere in loop. Alla riconnessione, ripartite da uno stato pulito: rieseguite il bind, resettate la mappa delle richieste in sospeso e affidatevi all'idempotenza per reinviare in sicurezza ciò che era in volo. Monitorate lo stato del bind, l'occupazione della finestra, la latenza submit/DLR e i tassi per codice di errore, e impostate allarmi su tutti.
Domande frequenti
Come dovrei assegnare il sequence_number?
Usate un contatore monotonicamente crescente da 1 fino a 0x7FFFFFFF, poi wrap. Mantenete una mappa dei sequence_number in sospeso con timeout così da correlare ogni risposta e rilevare le richieste che non ne hanno ricevuta alcuna.
Come evito la doppia fatturazione sui retry?
Rendete idempotente l'invio. Allegate un vostro riferimento (ad esempio user_message_reference), deduplicate su di esso e progettate i retry in modo che un reinvio dopo un timeout ambiguo venga riconosciuto e soppresso anziché consegnato e fatturato due volte.
Quali errori SMPP dovrei riprovare?
Riprovate quelli transitori — ESME_RMSGQFUL, ESME_RTHROTTLED, errori di sistema e timeout — con backoff esponenziale e jitter. Non riprovate errori permanenti come ESME_RINVDSTADR o ESME_RINVPASWD; correggete invece l'input o la configurazione.
Cosa dovrei monitorare su un bind SMPP?
Lo stato del bind, il tempo dall'ultimo enquire_link_resp, l'occupazione della finestra, la latenza di submit e DLR e i tassi di errore per codice (soprattutto ESME_RTHROTTLED). Impostate allarmi su throttling crescente o finestra bloccata come segnali precoci di problemi.
Come dovrei gestire la riconnessione dopo una sessione caduta?
Riconnettetevi con backoff esponenziale e jitter, rieseguite il bind, resettate la mappa delle richieste in sospeso e reinviate i messaggi in volo affidandovi all'idempotenza per prevenire duplicati. Non ripetete mai le riconnessioni in loop, cosa che può portare al blocco del vostro IP.
Specifiche della fonte
Gli standard pubblicati su cui si basa questa pagina. Si apre in una nuova scheda.