WebPush
TsgcHTMLWebPush: Web Push para um navegador que não está em execução ou que não está na sua página, em Delphi, C++ Builder e .NET. Disponível somente nas edições Enterprise e All-Access.
TsgcHTMLWebPush: Web Push para um navegador que não está em execução ou que não está na sua página, em Delphi, C++ Builder e .NET. Disponível somente nas edições Enterprise e All-Access.
O Web Push alcança um usuário cujo navegador está fechado ou exibindo outra página. A página se inscreve, a sua aplicação guarda a inscrição por meio de três eventos, e uma chamada a Send entrega a notificação. Disponível somente nas edições Enterprise e All-Access.
TsgcHTMLWebPush (unit sgcHTML_WebPush)
Sem markup: mensagens push criptografadas enviadas ao navegador
Delphi, C++ Builder, .NET
Gere um par de chaves VAPID uma vez e guarde-o. Atribua o par e um Subject, trate os eventos de armazenamento, defina WebPush no engine e WebPushEnabled no template dele, e então chame 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>
Os membros que você usa com mais frequência.
O Web Push está disponível somente nas edições Enterprise e All-Access. A unit compila quando SGC_WEBPUSH está definido, o que o sgcVer.inc faz para essas duas edições, e ela também precisa do próprio sgcHTML, que é vendido de forma independente. A caixa de entrada de notificações e a tabela de preferências fazem parte do sgcHTML e não precisam do Web Push: só o canal de push precisa.
GenerateVAPIDKeys é um método de classe que devolve um novo par: a metade pública é a application server key em base64url com a qual o navegador se inscreve, e a metade privada é uma chave EC em PEM. Atribua-as a VAPIDPublicKey e VAPIDPrivateKey. Subject é o contato VAPID, uma URI mailto: ou https:. A build padrão do Delphi carrega o OpenSSL 3.x para a criptografia e seleciona essa API por conta própria; a versão .NET usa criptografia gerenciada e não precisa do OpenSSL.
O componente não guarda nenhuma inscrição por conta própria. OnSaveSubscription(aUserID, aEndpoint, aP256dh, aAuth) guarda uma, OnLoadSubscriptions(aUserID, aList) preenche aList com um Add(endpoint, p256dh, auth) por inscrição guardada do usuário, e OnDeleteSubscription(aUserID, aEndpoint) remove uma. Cada entrada é um TsgcHTMLWebPushSubscription.
Send(aUserID, aTitle, aBody, aURL, aIcon, aTag, aTTL, aUrgency) criptografa uma notificação por inscrição guardada do usuário (RFC 8291) e a envia por POST ao serviço de push com uma assinatura VAPID (RFC 8292). Devolve para quantas inscrições entregou, ou 0 quando Enabled é False. O remetente, TsgcHTMLWebPushClient, reutiliza TsgcHTTP_API_WebPush_Client.
TTL tem 2419200 segundos (28 dias) como padrão e Urgency é vazio, o que não envia nenhum cabeçalho de urgência. Passe aTTL ou aUrgency a Send para substituir qualquer um dos dois em uma única notificação.
Quando um serviço de push responde 404 ou 410, OnSubscriptionExpired(aUserID, aEndpoint, aStatusCode) dispara para que você descarte a inscrição. Qualquer outra falha aciona OnSendError(aUserID, aEndpoint, E) e as inscrições restantes ainda são tentadas.
Depois que o componente é atribuído ao engine, um POST em SubscribeEndpoint (/push/subscribe) ou UnsubscribeEndpoint (/push/unsubscribe) é respondido para você: 204 quando tratado, 400 para uma inscrição inválida, 403 quando nenhum usuário é resolvido, 413 acima de 64 KB. Chame HandleSubscribe(aJSON, aUserID) e HandleUnsubscribe você mesmo para rotear os POSTs do seu jeito.
O usuário nunca é lido do que o navegador envia. Com um TsgcHTMLAuth no engine, é o usuário do cookie de sessão, e o token CSRF é exigido. Sem ele, OnResolveUser(aCookieHeader, aHeaders, aBody, aUserID, aAllowed) responde com o seu próprio id de usuário ou recusa. Sem nenhum dos dois, a requisição recebe 403.
Com Template.WebPushEnabled ligado, o engine copia a chave pública e os endpoints para o template, serve o service worker em ServiceWorkerPath e a página traz o script de inscrição. Coloque <button data-sgc-webpush> na página para que o pedido de permissão parta de um clique; data-sgc-webpush="unsubscribe" cancela a inscrição. Os navegadores exigem https, ou localhost durante o desenvolvimento.
TsgcHTMLComponent_Notification escolhe entre os dois. Atribua Presence e WebPush, responda OnGetChannel com ncPush e chame AddNotification(aUserID, aId, aTitle, aMessage, ...): um usuário conectado recebe a notificação na página, um usuário que não está conectado recebe um Send, e assim ninguém é avisado duas vezes. Sem um handler de OnGetChannel, nada é enviado por push.
| Ajuda onlineReferência completa da API e guia de uso para este componente. | Abrir | |
| Guia do Web PushComo as peças se encaixam: inscrições, VAPID, os endpoints do engine e o componente de notificação. | Abrir | |
| Todos os Componentes sgcHTMLExplore a matriz completa de recursos com mais de 80 componentes. | Abrir | |
| Baixar Versão de Avaliação GratuitaA avaliação de 30 dias inclui os projetos de demonstração 60.HTML, entre eles o 17.FieldService, que usa Web Push. | Abrir | |
| PreçosLicenças Single, Team e Site com código-fonte completo. | Abrir |