WebPush
TsgcHTMLWebPush: Web Push per un browser che non è in esecuzione o non è sulla tua pagina, in Delphi, C++ Builder e .NET. Disponibile solo nelle edizioni Enterprise e All-Access.
TsgcHTMLWebPush: Web Push per un browser che non è in esecuzione o non è sulla tua pagina, in Delphi, C++ Builder e .NET. Disponibile solo nelle edizioni Enterprise e All-Access.
Web Push raggiunge un utente il cui browser è chiuso o mostra un’altra pagina. La pagina crea una sottoscrizione, la tua applicazione la memorizza tramite tre eventi e una sola chiamata a Send consegna la notifica. Disponibile solo nelle edizioni Enterprise e All-Access.
TsgcHTMLWebPush (unit sgcHTML_WebPush)
Nessun markup: messaggi push cifrati inviati al browser
Delphi, C++ Builder, .NET
Genera una sola volta una coppia di chiavi VAPID e conservala. Assegna la coppia e un Subject, gestisci gli eventi di archiviazione, imposta WebPush sull’engine e WebPushEnabled sul suo template, quindi chiama Send.
// Enterprise and All-Access only: compiled when SGC_WEBPUSH is defined
uses
Data.DB, sgcHTML_WebPush, sgcHTMX_Engine_Server;
var
vPublic, vPrivate: string;
begin
// once, then keep both values in your own settings
TsgcHTMLWebPush.GenerateVAPIDKeys(vPublic, vPrivate);
FPush := TsgcHTMLWebPush.Create(Self);
FPush.VAPIDPublicKey := vPublic;
FPush.VAPIDPrivateKey := vPrivate;
FPush.Subject := 'mailto:support@example.com';
FPush.OnSaveSubscription := PushSave;
FPush.OnLoadSubscriptions := PushLoad;
FPush.OnDeleteSubscription := PushDelete;
FPush.OnSubscriptionExpired := PushExpired;
FPush.Enabled := True;
// oHTMX is a TsgcHTMX_Engine_Server
oHTMX.WebPush := FPush;
oHTMX.Template.WebPushEnabled := True;
// later, from anywhere in the application
FPush.Send('u1', 'Order shipped',
'Order 1042 left the warehouse', '/orders/1042');
end;
// the application owns the storage
procedure TForm1.PushSave(Sender: TObject;
const aUserID, aEndpoint, aP256dh, aAuth: string);
begin
SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
end;
procedure TForm1.PushLoad(Sender: TObject; const aUserID: string;
const aList: TsgcHTMLWebPushSubscriptions);
var
oQuery: TDataSet;
begin
oQuery := OpenSubscriptions(aUserID);
try
// one Add per stored subscription of this user
while not oQuery.Eof do
begin
aList.Add(oQuery.FieldByName('endpoint').AsString,
oQuery.FieldByName('p256dh').AsString,
oQuery.FieldByName('auth').AsString);
oQuery.Next;
end;
finally
oQuery.Free;
end;
end;
procedure TForm1.PushDelete(Sender: TObject; const aUserID, aEndpoint: string);
begin
DeleteSubscription(aUserID, aEndpoint);
end;
procedure TForm1.PushExpired(Sender: TObject;
const aUserID, aEndpoint: string; aStatusCode: Integer);
begin
// 404 or 410: the push service dropped it for good
DeleteSubscription(aUserID, aEndpoint);
end;
// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>
// includes: sgcHTML_WebPush.hpp, sgcHTMX_Engine_Server.hpp
// Enterprise and All-Access only: compiled when SGC_WEBPUSH is defined
String vPublic, vPrivate;
// once, then keep both values in your own settings
TsgcHTMLWebPush::GenerateVAPIDKeys(vPublic, vPrivate);
FPush = new TsgcHTMLWebPush(this);
FPush->VAPIDPublicKey = vPublic;
FPush->VAPIDPrivateKey = vPrivate;
FPush->Subject = "mailto:support@example.com";
FPush->OnSaveSubscription = PushSave;
FPush->OnLoadSubscriptions = PushLoad;
FPush->OnDeleteSubscription = PushDelete;
FPush->OnSubscriptionExpired = PushExpired;
FPush->Enabled = true;
// oHTMX is a TsgcHTMX_Engine_Server
oHTMX->WebPush = FPush;
oHTMX->Template->WebPushEnabled = true;
// later, from anywhere in the application
FPush->Send("u1", "Order shipped",
"Order 1042 left the warehouse", "/orders/1042");
// the application owns the storage
void __fastcall TForm1::PushSave(TObject *Sender,
const UnicodeString aUserID, const UnicodeString aEndpoint,
const UnicodeString aP256dh, const UnicodeString aAuth)
{
SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
}
void __fastcall TForm1::PushLoad(TObject *Sender, const UnicodeString aUserID,
TsgcHTMLWebPushSubscriptions *const aList)
{
// one Add per stored subscription of this user
for (const TStoredSubscription &row : LoadSubscriptions(aUserID))
aList->Add(row.Endpoint, row.P256dh, row.Auth);
}
// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>
using esegece.sgcWebSockets;
// once, then keep both values in your own settings
TsgcHTMLWebPush.GenerateVAPIDKeys(out var pub, out var priv);
var push = new TsgcHTMLWebPush();
push.VAPIDPublicKey = pub;
push.VAPIDPrivateKey = priv;
push.Subject = "mailto:support@example.com";
// the application owns the storage
push.OnSaveSubscription += (sender, aUserID, aEndpoint, aP256dh, aAuth) =>
SaveSubscription(aUserID, aEndpoint, aP256dh, aAuth);
push.OnLoadSubscriptions += (sender, aUserID, aList) =>
{
// one Add per stored subscription of this user
foreach (var row in LoadSubscriptions(aUserID))
aList.Add(row.Endpoint, row.P256dh, row.Auth);
};
push.OnDeleteSubscription += (sender, aUserID, aEndpoint) =>
DeleteSubscription(aUserID, aEndpoint);
push.OnSubscriptionExpired += (sender, aUserID, aEndpoint, aStatusCode) =>
DeleteSubscription(aUserID, aEndpoint); // 404 or 410: gone for good
push.Enabled = true;
// htmx is a TsgcHTMX_Engine_Server
htmx.WebPush = push;
htmx.Template.WebPushEnabled = true;
// later, from anywhere in the application
int delivered = push.Send("u1", "Order shipped",
"Order 1042 left the warehouse", "/orders/1042");
// in the page, a click starts the permission prompt:
// <button data-sgc-webpush>Enable notifications</button>
I membri che utilizzerai più spesso.
Web Push è disponibile solo nelle edizioni Enterprise e All-Access. L’unit compila quando è definito SGC_WEBPUSH, cosa che sgcVer.inc imposta per queste due edizioni, e richiede anche sgcHTML stesso, che si vende indipendentemente. L’inbox delle notifiche e la tabella delle preferenze fanno parte di sgcHTML e non lo richiedono: lo richiede solo il canale push.
GenerateVAPIDKeys è un metodo di classe che restituisce una nuova coppia: la metà pubblica è la chiave del server applicativo in base64url con cui il browser si sottoscrive, la metà privata una chiave EC in PEM. Assegnale a VAPIDPublicKey e VAPIDPrivateKey. Subject è il contatto VAPID, un URI mailto: o https:. La build Delphi standard carica OpenSSL 3.x per la crittografia e seleziona da sola quella API; la versione .NET usa crittografia gestita e non richiede OpenSSL.
Il componente non conserva alcuna sottoscrizione propria. OnSaveSubscription(aUserID, aEndpoint, aP256dh, aAuth) ne memorizza una, OnLoadSubscriptions(aUserID, aList) riempie aList con un Add(endpoint, p256dh, auth) per ogni sottoscrizione memorizzata dell’utente, e OnDeleteSubscription(aUserID, aEndpoint) ne rimuove una. Ogni voce è un TsgcHTMLWebPushSubscription.
Send(aUserID, aTitle, aBody, aURL, aIcon, aTag, aTTL, aUrgency) cifra una notifica per ogni sottoscrizione memorizzata dell’utente (RFC 8291) e la invia con POST al servizio push con una firma VAPID (RFC 8292). Restituisce il numero di sottoscrizioni a cui ha consegnato, oppure 0 quando Enabled è False. Il mittente, TsgcHTMLWebPushClient, riusa TsgcHTTP_API_WebPush_Client.
TTL vale per impostazione predefinita 2419200 secondi (28 giorni) e Urgency è vuoto, il che non invia alcun header di urgenza. Passa aTTL o aUrgency a Send per sostituire l’uno o l’altro per una singola notifica.
Quando un servizio push risponde 404 o 410, scatta OnSubscriptionExpired(aUserID, aEndpoint, aStatusCode) così puoi eliminare la sottoscrizione. Qualsiasi altro errore genera OnSendError(aUserID, aEndpoint, E) e le sottoscrizioni rimanenti vengono comunque provate.
Una volta assegnato il componente all’engine, un POST a SubscribeEndpoint (/push/subscribe) o UnsubscribeEndpoint (/push/unsubscribe) riceve risposta automaticamente: 204 se gestito, 400 per una sottoscrizione non valida, 403 quando non si risolve alcun utente, 413 oltre 64 KB. Chiama tu stesso HandleSubscribe(aJSON, aUserID) e HandleUnsubscribe per instradare i POST a modo tuo.
L’utente non viene mai letto da ciò che il browser invia. Con un TsgcHTMLAuth sull’engine è l’utente del cookie di sessione, e il token CSRF è obbligatorio. Senza, OnResolveUser(aCookieHeader, aHeaders, aBody, aUserID, aAllowed) risponde con il tuo id utente oppure rifiuta. Se non c’è né l’uno né l’altro, la richiesta riceve 403.
Con Template.WebPushEnabled attivo, l’engine copia la chiave pubblica e gli endpoint nel template, serve il service worker in ServiceWorkerPath e la pagina include lo script di sottoscrizione. Inserisci <button data-sgc-webpush> nella pagina in modo che la richiesta di permesso parta da un clic; data-sgc-webpush="unsubscribe" lo disattiva. I browser richiedono https, oppure localhost durante lo sviluppo.
TsgcHTMLComponent_Notification sceglie tra i due. Assegna Presence e WebPush, rispondi a OnGetChannel con ncPush e chiama AddNotification(aUserID, aId, aTitle, aMessage, ...): un utente connesso riceve la notifica nella pagina, un utente non connesso la riceve con un Send, così nessuno viene avvisato due volte. Senza un gestore OnGetChannel non viene mai inviato alcun push.
| Guida in lineaRiferimento API completo e guida all’uso per questo componente. | Apri | |
| Guida a Web PushCome si combinano le varie parti: sottoscrizioni, VAPID, gli endpoint dell’engine e il componente di notifica. | Apri | |
| Tutti i componenti sgcHTMLEsplora la matrice completa delle funzionalità di oltre 80 componenti. | Apri | |
| Scarica la Prova GratuitaLa prova di 30 giorni include i progetti demo 60.HTML, tra cui 17.FieldService, che usa Web Push. | Apri | |
| PrezziLicenze Single, Team e Site con codice sorgente completo. | Apri |