Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Delphi DLL) Firebase Receive Server-Sent Events (text/event-stream)Demonstrates how to start receiving server-sent events and update your JSON database with each event.
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, AuthGoogle, Url, FileAccess, Stream, Rest, JsonObject, ServerSentEvent, Task; ... procedure TForm1.Button1Click(Sender: TObject); var fac: HCkFileAccess; accessToken: PWideChar; rest: HCkRest; success: Boolean; authGoogle: HCkAuthGoogle; responseBody: PWideChar; url: HCkUrl; rest2: HCkRest; responseStatusCode: Integer; jsonDb: HCkJsonObject; eventStream: HCkStream; sse: HCkServerSentEvent; task: HCkTask; count: Integer; eventStr: PWideChar; begin // Demonstrates how to begin receiving server-sent events, and to update // your JSON database for each event. // This example requires the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. // This example assumes a JWT authentication token, if required, has been previously obtained. // See Get Firebase Access Token from JSON Service Account Private Key for sample code. // Load the previously obtained Firebase access token into a string. fac := CkFileAccess_Create(); accessToken := CkFileAccess__readEntireTextFile(fac,'qa_data/tokens/firebaseToken.txt','utf-8'); if (CkFileAccess_getLastMethodSuccess(fac) <> True) then begin Memo1.Lines.Add(CkFileAccess__lastErrorText(fac)); Exit; end; rest := CkRest_Create(); // Make the initial connection (without sending a request yet). // Once connected, any number of requests may be sent. It is not necessary to explicitly // call Connect before each request. success := CkRest_Connect(rest,'chilkat.firebaseio.com',443,True,True); if (success <> True) then begin Memo1.Lines.Add(CkRest__lastErrorText(rest)); Exit; end; authGoogle := CkAuthGoogle_Create(); CkAuthGoogle_putAccessToken(authGoogle,accessToken); CkRest_SetAuthGoogle(rest,authGoogle); CkRest_AddHeader(rest,'Accept','text/event-stream'); CkRest_AddHeader(rest,'Cache-Control','no-cache'); responseBody := CkRest__fullRequestNoBody(rest,'GET','/.json'); // A 307 redirect response is expected. if (CkRest_getResponseStatusCode(rest) <> 307) then begin Memo1.Lines.Add('Unexpected response code: ' + IntToStr(CkRest_getResponseStatusCode(rest))); Memo1.Lines.Add(responseBody); Memo1.Lines.Add('Failed.'); Exit; end; // Get the redirect URL url := CkRest_RedirectUrl(rest); if (CkRest_getLastMethodSuccess(rest) <> True) then begin Memo1.Lines.Add(CkRest__lastErrorText(rest)); Exit; end; Memo1.Lines.Add('redirect URL domain: ' + CkUrl__host(url)); Memo1.Lines.Add('redirect URL path: ' + CkUrl__path(url)); Memo1.Lines.Add('redirect URL query params: ' + CkUrl__query(url)); Memo1.Lines.Add('redirect URL path with query params: ' + CkUrl__pathWithQueryParams(url)); // Our text/event-stream will be obtained from the redirect URL... rest2 := CkRest_Create(); success := CkRest_Connect(rest2,CkUrl__host(url),443,True,True); if (success <> True) then begin Memo1.Lines.Add(CkRest__lastErrorText(rest2)); CkUrl_Dispose(url); Exit; end; CkRest_AddHeader(rest2,'Accept','text/event-stream'); CkRest_AddHeader(rest2,'Cache-Control','no-cache'); // Add the redirect query params to the request CkRest_AddQueryParams(rest2,CkUrl__query(url)); // In our case, we don't actually need the auth query param, // so remove it. CkRest_RemoveQueryParam(rest2,'auth'); // Send the request. (We are only sending the request here. // We are not yet getting the response because the response // will be a text/event-stream.) success := CkRest_SendReqNoBody(rest2,'GET',CkUrl__path(url)); if (success <> True) then begin Memo1.Lines.Add(CkRest__lastErrorText(rest2)); CkUrl_Dispose(url); Exit; end; CkUrl_Dispose(url); // Read the response header. // We want to first get the response header to see if it's a successful // response status code. If not, then the response will not be a text/event-stream // and we should read the response body normally. responseStatusCode := CkRest_ReadResponseHeader(rest2); if (responseStatusCode < 0) then begin Memo1.Lines.Add(CkRest__lastErrorText(rest2)); Exit; end; // If successful, a 200 response code is expected. // If the reponse code is not 200, then read the response body and fail.. if (responseStatusCode <> 200) then begin Memo1.Lines.Add('Response Code: ' + IntToStr(responseStatusCode)); Memo1.Lines.Add('Response Status Text: ' + CkRest__responseStatusText(rest2)); Memo1.Lines.Add('Response Header: ' + CkRest__responseHeader(rest2)); responseBody := CkRest__readRespBodyString(rest2); if (CkRest_getLastMethodSuccess(rest2) = True) then begin Memo1.Lines.Add('Error Response Body: ' + responseBody); end; Memo1.Lines.Add('Failed.'); Exit; end; // For this example, our JSON database will be empty at the beginning. // The incoming events (put and patch) will be applied to this database. jsonDb := CkJsonObject_Create(); // Make sure to set the JSON path delimiter to "/". The default is "." and this // is not compatible with Firebase paths. CkJsonObject_putDelimiterChar(jsonDb,'/'); // At this point, we've received the response header. Now it's time to begin // receiving the event stream. We'll start a background thread to read the // stream. (Our main application (foreground) thread can cancel it at any time.) // While receiving in the background thread, our foreground thread can read the stream // as it desires.. eventStream := CkStream_Create(); // This sse object will be used as a helper to parse the server-sent event stream. sse := CkServerSentEvent_Create(); task := CkRest_ReadRespBodyStreamAsync(rest2,eventStream,True); CkTask_Run(task); // For this example, we'll just read a few events, and then cancel the // async task. count := 0; while (count < 3) and (CkTask_getFinished(task) = False) do begin // Get the next event, which is a series of text lines ending with // a blank line. // Note: This method blocks the calling thread until a message arrives. // a program might instead periodically check the availability of // data via the stream's DataAvailable property, and then do the read. // An alternative to writing a while loop to read the event stream // would be to setup some sort of timer event in your program (using whatever timer functionality // is provided in a programming language/environment), to periodically check the eventStream's // DataAvailable property and consume the incoming event. eventStr := CkStream__readUntilMatch(eventStream,#13#10 + #13#10); if (CkStream_getLastMethodSuccess(eventStream) <> True) then begin Memo1.Lines.Add(CkStream__lastErrorText(eventStream)); // Force the loop to exit by setting the count to a high number. count := 99999; end else begin Memo1.Lines.Add('Event: [' + eventStr + ']'); // We have an event. Let's update our local copy of the JSON database. success := CkServerSentEvent_LoadEvent(sse,eventStr); if (success <> True) then begin Memo1.Lines.Add('Failed to load sse event: ' + eventStr); end else begin // Now we can easily access the event name and data, and apply it to our JSON database: success := CkJsonObject_FirebaseApplyEvent(jsonDb,CkServerSentEvent__eventName(sse),CkServerSentEvent__data(sse)); if (success <> True) then begin Memo1.Lines.Add('Failed to apply event: ' + CkServerSentEvent__eventName(sse) + ': ' + CkServerSentEvent__data(sse)); end else begin Memo1.Lines.Add('Successfully applied event: ' + CkServerSentEvent__eventName(sse) + ': ' + CkServerSentEvent__data(sse)); end; end; end; count := count + 1; end; // Make sure the background task is cancelled if still running. CkTask_Cancel(task); CkTask_Dispose(task); // Examine the JSON database after applying events.. CkJsonObject_putEmitCompact(jsonDb,False); Memo1.Lines.Add('----'); Memo1.Lines.Add(CkJsonObject__emit(jsonDb)); CkFileAccess_Dispose(fac); CkRest_Dispose(rest); CkAuthGoogle_Dispose(authGoogle); CkRest_Dispose(rest2); CkJsonObject_Dispose(jsonDb); CkStream_Dispose(eventStream); CkServerSentEvent_Dispose(sse); end; |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.