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
(Swift 2) Firebase Receive Server-Sent Events (text/event-stream)Demonstrates how to start receiving server-sent events and update your JSON database with each event.
func chilkatTest() { // 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. let fac = CkoFileAccess() var accessToken: String? = fac.ReadEntireTextFile("qa_data/tokens/firebaseToken.txt", charset: "utf-8") if fac.LastMethodSuccess != true { print("\(fac.LastErrorText)") return } let rest = CkoRest() // 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. var success: Bool = rest.Connect("chilkat.firebaseio.com", port: 443, tls: true, autoReconnect: true) if success != true { print("\(rest.LastErrorText)") return } let authGoogle = CkoAuthGoogle() authGoogle.AccessToken = accessToken rest.SetAuthGoogle(authGoogle) rest.AddHeader("Accept", value: "text/event-stream") rest.AddHeader("Cache-Control", value: "no-cache") var responseBody: String? = rest.FullRequestNoBody("GET", uriPath: "/.json") // A 307 redirect response is expected. if rest.ResponseStatusCode.intValue != 307 { print("Unexpected response code: \(rest.ResponseStatusCode.intValue)") print("\(responseBody!)") print("Failed.") return } // Get the redirect URL var url: CkoUrl? = rest.RedirectUrl() if rest.LastMethodSuccess != true { print("\(rest.LastErrorText)") return } print("redirect URL domain: \(url!.Host)") print("redirect URL path: \(url!.Path)") print("redirect URL query params: \(url!.Query)") print("redirect URL path with query params: \(url!.PathWithQueryParams)") // Our text/event-stream will be obtained from the redirect URL... let rest2 = CkoRest() success = rest2.Connect(url!.Host, port: 443, tls: true, autoReconnect: true) if success != true { print("\(rest2.LastErrorText)") url = nil return } rest2.AddHeader("Accept", value: "text/event-stream") rest2.AddHeader("Cache-Control", value: "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", uriPath: url!.Path) if success != true { print("\(rest2.LastErrorText)") url = nil return } url = nil // 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. var responseStatusCode: Int = rest2.ReadResponseHeader().intValue if responseStatusCode < 0 { print("\(rest2.LastErrorText)") 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 { print("Response Code: \(responseStatusCode)") print("Response Status Text: \(rest2.ResponseStatusText)") print("Response Header: \(rest2.ResponseHeader)") responseBody = rest2.ReadRespBodyString() if rest2.LastMethodSuccess == true { print("Error Response Body: \(responseBody!)") } print("Failed.") 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. let jsonDb = CkoJsonObject() // Make sure to set the JSON path delimiter to "/". The default is "." and this // is not compatible with Firebase paths. jsonDb.DelimiterChar = "/" // 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.. let eventStream = CkoStream() // This sse object will be used as a helper to parse the server-sent event stream. let sse = CkoServerSentEvent() var task: CkoTask? = rest2.ReadRespBodyStreamAsync(eventStream, autoSetStreamCharset: true) task!.Run() // For this example, we'll just read a few events, and then cancel the // async task. var count: Int = 0 while (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. var eventStr: String? = eventStream.ReadUntilMatch("\r\n\r\n") if eventStream.LastMethodSuccess != true { print("\(eventStream.LastErrorText)") // Force the loop to exit by setting the count to a high number. count = 99999 } else { print("Event: [\(eventStr!)]") // We have an event. Let's update our local copy of the JSON database. success = sse.LoadEvent(eventStr) if success != true { print("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, data: sse.Data) if success != true { print("Failed to apply event: \(sse.EventName): \(sse.Data)") } else { print("Successfully applied event: \(sse.EventName): \(sse.Data)") } } } count = count + 1 } // Make sure the background task is cancelled if still running. task!.Cancel() task = nil // Examine the JSON database after applying events.. jsonDb.EmitCompact = false print("----") print("\(jsonDb.Emit())") } |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.