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 3,4,5...) 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.read(untilMatch: "\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.load(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.