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
(Go) Firebase Receive Server-Sent Events (text/event-stream)Demonstrates how to start receiving server-sent events and update your JSON database with each event.
// 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 := chilkat.NewFileAccess() accessToken := fac.ReadEntireTextFile("qa_data/tokens/firebaseToken.txt","utf-8") if fac.LastMethodSuccess() != true { fmt.Println(fac.LastErrorText()) fac.DisposeFileAccess() return } rest := chilkat.NewRest() // 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 := rest.Connect("chilkat.firebaseio.com",443,true,true) if success != true { fmt.Println(rest.LastErrorText()) fac.DisposeFileAccess() rest.DisposeRest() return } authGoogle := chilkat.NewAuthGoogle() authGoogle.SetAccessToken(*accessToken) rest.SetAuthGoogle(authGoogle) rest.AddHeader("Accept","text/event-stream") rest.AddHeader("Cache-Control","no-cache") responseBody := rest.FullRequestNoBody("GET","/.json") // A 307 redirect response is expected. if rest.ResponseStatusCode() != 307 { fmt.Println("Unexpected response code: ", rest.ResponseStatusCode()) fmt.Println(*responseBody) fmt.Println("Failed.") fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() return } // Get the redirect URL url := rest.RedirectUrl() if rest.LastMethodSuccess() != true { fmt.Println(rest.LastErrorText()) fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() return } fmt.Println("redirect URL domain: ", url.Host()) fmt.Println("redirect URL path: ", url.Path()) fmt.Println("redirect URL query params: ", url.Query()) fmt.Println("redirect URL path with query params: ", url.PathWithQueryParams()) // Our text/event-stream will be obtained from the redirect URL... rest2 := chilkat.NewRest() success = rest2.Connect(url.Host(),443,true,true) if success != true { fmt.Println(rest2.LastErrorText()) url.DisposeUrl() fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() rest2.DisposeRest() return } rest2.AddHeader("Accept","text/event-stream") rest2.AddHeader("Cache-Control","no-cache") // Add the redirect query params to the request rest2.AddQueryParams(url.Query()) // In our case, we don't actually need the auth query param, // so remove it. rest2.RemoveQueryParam("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 = rest2.SendReqNoBody("GET",url.Path()) if success != true { fmt.Println(rest2.LastErrorText()) url.DisposeUrl() fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() rest2.DisposeRest() return } url.DisposeUrl() // 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 := rest2.ReadResponseHeader() if responseStatusCode < 0 { fmt.Println(rest2.LastErrorText()) fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() rest2.DisposeRest() return } // 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 { fmt.Println("Response Code: ", responseStatusCode) fmt.Println("Response Status Text: ", rest2.ResponseStatusText()) fmt.Println("Response Header: ", rest2.ResponseHeader()) responseBody = rest2.ReadRespBodyString() if rest2.LastMethodSuccess() == true { fmt.Println("Error Response Body: ", *responseBody) } fmt.Println("Failed.") fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() rest2.DisposeRest() return } // 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 := chilkat.NewJsonObject() // Make sure to set the JSON path delimiter to "/". The default is "." and this // is not compatible with Firebase paths. jsonDb.SetDelimiterChar("/") // 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 := chilkat.NewStream() // This sse object will be used as a helper to parse the server-sent event stream. sse := chilkat.NewServerSentEvent() c := make(chan *chilkat.Task) go rest2.ReadRespBodyStreamAsync(eventStream,true,c) task := <-c // For this example, we'll just read a few events, and then cancel the // async task. count := 0 for (count < 3) && (task.Finished() == false) { // 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 := eventStream.ReadUntilMatch("\r\n\r\n") if eventStream.LastMethodSuccess() != true { fmt.Println(eventStream.LastErrorText()) // Force the loop to exit by setting the count to a high number. count = 99999 } else { fmt.Println("Event: [", *eventStr, "]") // We have an event. Let's update our local copy of the JSON database. success = sse.LoadEvent(*eventStr) if success != true { fmt.Println("Failed to load sse event: ", *eventStr) } else { // Now we can easily access the event name and data, and apply it to our JSON database: success = jsonDb.FirebaseApplyEvent(sse.EventName(),sse.Data()) if success != true { fmt.Println("Failed to apply event: ", sse.EventName(), ": ", sse.Data()) } else { fmt.Println("Successfully applied event: ", sse.EventName(), ": ", sse.Data()) } } } count = count + 1 } // Make sure the background task is cancelled if still running. task.Cancel() task.DisposeTask() // Examine the JSON database after applying events.. jsonDb.SetEmitCompact(false) fmt.Println("----") fmt.Println(*jsonDb.Emit()) fac.DisposeFileAccess() rest.DisposeRest() authGoogle.DisposeAuthGoogle() rest2.DisposeRest() jsonDb.DisposeJsonObject() eventStream.DisposeStream() sse.DisposeServerSentEvent() task.DisposeTask() |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.