ASP.NET Core SignalR is een open-source bibliotheek die het eenvoudiger maakt om realtime webfunctionaliteit aan apps toe te voegen. Met realtime webfunctionaliteit kan code aan de serverzijde inhoud direct naar clients pushen.
Goede kandidaten voor SignalR:
Het SignalRCore sgcWebSockets-component gebruikt WebSocket als transport om verbinding te maken met een SignalRCore-server; als dit transport niet wordt ondersteund, wordt een fout gegenereerd.
SignalRCore uses hubs to communicate between clients and servers. SignalRCore provides 2 hub protocols: tekst protocol based on JSON and binair protocol based on MessagePack. The sgcWebSockets component only implements JSON tekst protocol to communicate with SignalRCore servers.
Om te configureren welke Hub-client zal worden gebruikt, stelt u de naam van de Hub in de eigenschap SignalRCore/Hub in voordat de client verbinding maakt met de server.
Wanneer een client een nieuwe verbinding opent met de server, verzendt het een aanvraagbericht dat het formaatprotocol en de versie bevat. sgcWebSockets verzendt altijd formaatprotocol als JSON. De server antwoordt met een fout als het protocol niet wordt ondersteund, deze fout kan worden afgehandeld via de OnSignalRCoreError-gebeurtenis, en als de verbinding succesvol is, wordt de OnSignalRCoreConnect-gebeurtenis aangeroepen.
Wanneer een client verbinding maakt met een SignalRCore-server, kan deze een ConnectionId verzenden die de client tussen sessies identificeert, zodat als er een verbreking optreedt, de client opnieuw verbinding kan maken met de server met dezelfde eerdere verbindings-id. Om een nieuwe verbindings-id te verkrijgen, maakt u gewoon normaal verbinding met de server en kunt u de ConnectionId ophalen via OnBeforeConnectEvent. Als u opnieuw verbinding wilt maken met de server en een eerdere verbindings-id wilt doorgeven, gebruikt u de methode ReConnect en geeft u ConnectionId als parameter door.
Het SignalR-protocol is een protocol voor tweerichtings-RPC via elk berichtengebaseerd transport. Beide partijen in de verbinding kunnen procedures aanroepen op de andere partij, en procedures kunnen nul of meer resultaten of een fout retourneren. Voorbeeld: de client kan een methode van de server aanvragen en de server kan een methode van de client aanvragen. De volgende berichten worden uitgewisseld tussen server en clients:
HandshakeRequest: de client verzendt dit naar de server om overeenstemming te bereiken over het berichtformaat.
HandshakeResponse: de server antwoordt de client met een bevestiging van het vorige HandshakeRequest-bericht. Bevat een fout als de handshake is mislukt.
Close: aangeroepen door client of server wanneer een verbinding wordt gesloten. Bevat een fout als de verbinding werd gesloten vanwege een fout.
Aanroep: client of server stuurt een bericht naar een andere peer om een methode aan te roepen met of zonder argumenten.
StreamInvocation: client of server verzendt een bericht naar een andere peer om een streamingmethode aan te roepen met of zonder argumenten. Het antwoord wordt opgesplitst in verschillende items.
StreamItem: is een antwoord op een eerdere StreamInvocation.
Completion: betekent dat een eerdere aanroep of StreamInvocation is voltooid. Kan een resultaat bevatten als het proces succesvol was, of een fout als er een probleem was.
CancelInvocation: annuleer een eerder StreamInvocation-verzoek.
Ping: is een bericht to check if the verbinding is still alive.
SignalRCore staat u toe de volgende coderingen te gebruiken:
Momenteel wordt alleen JSON ondersteund, hoewel MessagePack kan worden gebruikt door berichten te coderen met een externe messagepack-bibliotheek. Zie het gedeelte MessagePack hieronder voor meer informatie.
De configuratie van het coderingsprotocol wordt gedefinieerd in de eigenschap SignalRCore.Protocol. Standaard is de waarde srcpJSON.
Authenticatie kan worden ingeschakeld om een gebruiker te koppelen aan elke verbinding en te filteren welke gebruikers toegang hebben tot bronnen. Authenticatie wordt geïmplementeerd via Bearer Tokens: de client verstrekt een toegangstoken en de server valideert dit token en gebruikt het om de gebruiker te identificeren.
In standaard web-API's worden bearer-tokens verzonden in een HTTP-header, maar bij gebruik van WebSockets wordt het token doorgegeven als een querytekenreeksparameter.
De volgende methoden worden ondersteund:
srcaRequestToken
Als authenticatie is ingeschakeld, is de stroom:
1. Probeert eerst een geldig token van de server te krijgen. Opent een HTTP-verbinding tegen Authentication.RequestToken.URL en doet een POST met behulp van de User- en Password-gegevens.
2. Als het vorige succesvol is, wordt een token geretourneerd. Zo niet, dan wordt een fout geretourneerd.
3. Als het token wordt geretourneerd, opent het een nieuwe HTTP-verbinding om een nieuwe verbinding te onderhandelen. Hier wordt het token doorgegeven als een HTTP-header.
4. Als het vorige is gelukt, wordt een WebSocket-verbinding geopend en het token als querystring-parameter doorgegeven.
Authentication.Enabled: als actief, wordt autorisatie gebruikt voordat een websocket-verbinding tot stand wordt gebracht.
Authentication.Username: de gebruikersnaam die aan de server wordt verstrekt voor verificatie.
Authentication.Password: het geheime woord dat aan de server wordt verstrekt voor authenticatie.
Authentication.RequestToken.PostFieldUsername: naam van het veld om de username te verzenden (afhankelijk van de configuratie, controleer de http-javascript-pagina om te zien welke naam wordt gebruikt).
Authentication.RequestToken.PostFieldPassword: naam van het veld om het wachtwoord te verzenden (afhankelijk van de configuratie; raadpleeg de HTTP-JavaScript-pagina om te zien welke naam wordt gebruikt).
Authentication.RequestToken.URL: URL waarop het token wordt aangevraagd.
Authenticatie.RequestToken.QueryFieldToken: name of query tekenreeks parameter using in websocket verbinding.
srcaSetToken
Hier geeft u het token rechtstreeks door aan de SignalRCore-server (omdat het token is verkregen van een andere server).
Authentication.Enabled: als actief, wordt autorisatie gebruikt voordat een websocket-verbinding tot stand wordt gebracht.
Authentication.SetToken.Token: verkregen tokenwaarde.
Het toegangstoken kan worden verzonden als een queryparameter (dit is de standaardoptie) of als een HTTP-header als Bearer Token. Gebruik de eigenschap Authentication.TokenParam om dit gedrag te configureren.
srcaBasic
Deze optie gebruikt Basisauthenticatie; deze authenticatiemethode vereist het configureren van het SignalRCore-component en de TsgcWebSocketClient.
Voorbeeld: als de server basisauthenticatie vereist en de gebruikersnaam "user" en het wachtwoord "secret" zijn, configureert u de componenten zoals hieronder weergegeven.
// websocket client
WSClient := TsgcWebSocketClient.Create(nil);
WSClient.Authentication.Enabled := True;
WSClient.Authentication.Basic.Enabled := True;
WSClient.Authentication.URL.Enabled := False;
WSClient.Authentication.Session.Enabled := False;
WSClient.Authentication.Token.Enabled := False;
WSClient.Authentication.User := 'user';
WSClient.Authentication.Password := 'secret';
// signalrcore
Signal := TsgcWSAPI_SignalRCore.Create(nil);
Signal.SignalRCore.Authentication.Enabled := True;
Signal.SignalRCore.Authentication.Authentication := srcaBasic;
Signal.SignalRCore.Authentication.Username := 'user';
Signal.SignalRCore.Authentication.Password := 'secret';
Signal.Client := WSClient;
Er zijn drie soorten interacties tussen server en clients:
De aanroeper stuurt een bericht naar de aangeroepene en verwacht een bericht dat aangeeft dat de aanroep is voltooid en optioneel een resultaat van de aanroep
Voorbeeld: client roept de methode SendMessage aan en geeft als parameters de gebruikersnaam en het tekstbericht door. Verzendt een aanroep-id om
een resultaatbericht van de server te ontvangen.
SignalRCore.Invoke('SendMessage', ['John', 'Hello All.'], 'id-000001');
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);
begin
if Completion.Error <> '' then
ShowMessage('Something goes wrong.')
else
ShowMessage('Invocation Successful!');
end;
De aanroeper stuurt een bericht naar de aangeroepene en verwacht geen verdere berichten voor deze aanroep. Aanroepen kunnen worden verzonden zonder een Aanroep-ID-waarde. Dit geeft aan dat de aanroep "niet-blokkerend" is.
Voorbeeld: client roept de methode SendMessage aan en geeft als parameters de gebruikersnaam en tekstbericht mee. De client verwacht geen reactie van de server over het resultaat van de aanroep.
SignalRCore.Invoke('SendMessage', ['John', 'Hello All.']);
De Caller verzendt een bericht naar de Callee en verwacht één of meer resultaten die door de Callee worden geretourneerd, gevolgd door een bericht dat het einde van de aanroep aangeeft.
Voorbeeld: de client roept de methode Counter aan en vraagt 10 nummers op met een interval van 500 milliseconden.
SignalRCore.InvokeStream('Counter', [10, 500], 'id-000002');
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
DoLog('#stream item: ' + StreamItem.Item);
end;
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);
begin
if Completion.Error '' then
ShowMessage('Something goes wrong.')
else
ShowMessage('Invocation Successful!');
end;
Om een enkele aanroep uit te voeren, volgt de aanroeper de volgende basisstroom:
procedure Invoke(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String = '');
procedure InvokeStream(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String);
Wijs een uniek aanroep-ID-waarde toe (willekeurige tekenreeks, gekozen door de aanroeper) om de aanroep te vertegenwoordigen. Roep de methode Invoke of InvokeStream aan met het te roepen doel, de argumenten en de InvocationId (als u geen InvocationId stuurt, ontvangt u geen voltooiingsresultaat).
Als de aanroep is gemarkeerd als niet-blokkerend (zie "Niet-blokkerende aanroepen" hieronder), stopt u hier en geeft u de controle onmiddellijk terug aan de applicatie. Verwerk het StreamItem- of Completion-bericht met een overeenkomend aanroep-ID.
SignalRCore.InvokeStream('Counter', [10, 500], 'id-000002');
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
if StreamItem.InvocationId = 'id-000002' then
DoLog('#stream item: ' + StreamItem.Item);
end;
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);
begin
if StreamItem.InvocationId = 'id-000002' then
begin
if Completion.Error '' then
ShowMessage('Something goes wrong.')
else
ShowMessage('Invocation Successful!');
end;
end;
U kunt één aanroep doen en wachten op voltooiing.
function InvokeAndWait(const aTarget: String; aArguments: Array of Const; aInvocationId: String; out Completion: TSignalRCore_Completion;
const aTimeout: Integer = 10000): Boolean;
function InvokeStreamAndWait(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String;
out Completion: TSignalRCore_Completion; const aTimeout: Integer = 10000): Boolean;
Wijs een unieke aanroep-ID-waarde toe (willekeurige string, gekozen door de aanroeper) om de aanroep te vertegenwoordigen. Roep de methode InvokeAndWait of InvokeStreamAndWait aan met het doel dat wordt aangeroepen, Arguments en InvocationId. Het programma wacht totdat de voltooiingsgebeurtenis wordt aangeroepen of de time-out is overschreden.
var
oCompletion: TSignalRCore_Completion;
begin
if SignalRCore.InvokeStreamAndWait('Counter', [10, 500], 'id-000002', oCompletion) then
DoLog('#invoke stream ok: ' + oCompletion.Result)
else
DoLog('#invocke stream error: ' + oCompletion.Error);
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
if StreamItem.InvocationId = 'id-000002' then
DoLog('#stream item: ' + StreamItem.Item);
end;
Als de client wil stoppen met het ontvangen van StreamItem-berichten voordat de server een Completion-bericht verzendt, kan de client een CancelInvocation-bericht verzenden met dezelfde InvocationId die is gebruikt voor het StreamInvocation-bericht dat de stream heeft gestart.
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: SignalRCore_StreamItem; var Cancel: Boolean);
begin
if StreamItem.InvocationId = 'id-000002' then
Cancel := True;
end;
Een aanroep wordt pas als voltooid beschouwd wanneer het Completion-bericht is ontvangen. Als de client een aanroep ontvangt van de server, wordt de gebeurtenis OnSignalRCoreInvocation aangeroepen.
procedure OnSignalRCoreInvocation(Sender: TObject; Invocation: TSignalRCore_Invocation);
begin
if Invocation.Target = 'SendMessage' then
... your code here ...
end;
// Once invocation is completed, call Completion method to inform server invocation is finished.
// If result is successful, then call CompletionResult method:
SignalRCore.CompletionResult('id-000002', 'ok');
// If not, then call CompletionError method:
SignalRCore.CompletionError('id-000002', 'Error processing invocation.');
Verzonden door de client wanneer een verbinding wordt gesloten. Bevat een foutreden als de verbinding werd gesloten vanwege een fout.
SignalRCore.Close('Unexpected message').
// If the server close connection by any reason, OnSignalRCoreClose event will be called.
procedure OnSignalRCoreClose(Sender: TObject; Close: TSignalRCore_Close);
begin
DoLog('#closed: ' + Close.Error);
end;
Het SignalR Hub-protocol ondersteunt "Keep Alive"-berichten om te zorgen dat de onderliggende transportverbinding actief blijft. Deze berichten helpen het volgende te waarborgen:
Proxies sluiten de onderliggende verbinding niet tijdens inactieve periodes (wanneer er weinig berichten worden verzonden). Als de onderliggende verbinding wordt verbroken zonder netjes te worden beëindigd, wordt de toepassing zo snel mogelijk geïnformeerd.
Keep alive-gedrag wordt bereikt door de Ping-methode aan te roepen of HeartBeat in te schakelen op de WebSocket-client. Als de server een ping naar de client stuurt, stuurt de client automatisch een antwoord en wordt de gebeurtenis OnSignalRCoreKeepAlive aangeroepen.
procedure OnSignalRCoreKeepAlive(Sender: TObject);
begin
DoLog('#keepalive');
end;
In de MsgPack-codering van het SignalR-protocol wordt elk bericht weergegeven als een enkele MsgPack-array met elementen die overeenkomen met eigenschappen van het gegeven hub-protocolbericht. De array-elementen kunnen primitieve waarden, arrays (bijv. methodeargumenten) of objecten (bijv. argumentwaarden) zijn. Het eerste element in de array is het berichttype.
Raadpleeg de MessagePack-documentatie om te zien hoe de verzonden berichten gecodeerd moeten worden.
Elke keer dat een nieuw bericht wordt ontvangen, wordt dit gedispatcht in de gebeurtenis OnSignalRCoreMessagePack. Het bericht kan worden gelezen via de parameter Data Stream. De parameter JSON is standaard leeg; als u het MessagePack-bericht converteert naar JSON, verwerkt de component het JSON-bericht alsof de codering JSON was (zodat de gebeurtenissen OnSignalRCoreCompletion, OnSignalRCoreInvocation... worden gedispatcht).