Perl
Perl
Firebase Receive Server-Sent Events (text/event-stream)
See more Firebase Examples
Demonstrates how to start receiving server-sent events and update your JSON database with each event.Chilkat Perl Downloads
use chilkat();
$success = 0;
# 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::CkFileAccess->new();
$accessToken = $fac->readEntireTextFile("qa_data/tokens/firebaseToken.txt","utf-8");
if ($fac->get_LastMethodSuccess() == 0) {
print $fac->lastErrorText() . "\r\n";
exit;
}
$rest = chilkat::CkRest->new();
# 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,1,1);
if ($success == 0) {
print $rest->lastErrorText() . "\r\n";
exit;
}
$authGoogle = chilkat::CkAuthGoogle->new();
$authGoogle->put_AccessToken($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->get_ResponseStatusCode() != 307) {
print "Unexpected response code: " . $rest->get_ResponseStatusCode() . "\r\n";
print $responseBody . "\r\n";
print "Failed." . "\r\n";
exit;
}
# Get the redirect URL
$urlStr = $rest->lastRedirectUrl();
$url = chilkat::CkUrl->new();
$url->ParseUrl($urlStr);
print "redirect URL domain: " . $url->host() . "\r\n";
print "redirect URL path: " . $url->path() . "\r\n";
print "redirect URL query params: " . $url->query() . "\r\n";
print "redirect URL path with query params: " . $url->pathWithQueryParams() . "\r\n";
# Our text/event-stream will be obtained from the redirect URL...
$rest2 = chilkat::CkRest->new();
$success = $rest2->Connect($url->host(),443,1,1);
if ($success != 1) {
print $rest2->lastErrorText() . "\r\n";
exit;
}
$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 != 1) {
print $rest2->lastErrorText() . "\r\n";
exit;
}
# 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) {
print $rest2->lastErrorText() . "\r\n";
exit;
}
# 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 . "\r\n";
print "Response Status Text: " . $rest2->responseStatusText() . "\r\n";
print "Response Header: " . $rest2->responseHeader() . "\r\n";
$responseBody = $rest2->readRespBodyString();
if ($rest2->get_LastMethodSuccess() == 1) {
print "Error Response Body: " . $responseBody . "\r\n";
}
print "Failed." . "\r\n";
exit;
}
# 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::CkJsonObject->new();
# Make sure to set the JSON path delimiter to "/". The default is "." and this
# is not compatible with Firebase paths.
$jsonDb->put_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..
$eventStream = chilkat::CkStream->new();
# This sse object will be used as a helper to parse the server-sent event stream.
$sse = chilkat::CkServerSentEvent->new();
# task is a Task
$task = $rest2->ReadRespBodyStreamAsync($eventStream,1);
$task->Run();
# For this example, we'll just read a few events, and then cancel the
# async task.
$count = 0;
while (($count < 3) and ($task->get_Finished() == 0)) {
# 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->get_LastMethodSuccess() != 1) {
print $eventStream->lastErrorText() . "\r\n";
# Force the loop to exit by setting the count to a high number.
$count = 99999;
}
else {
print "Event: [" . $eventStr . "]" . "\r\n";
# We have an event. Let's update our local copy of the JSON database.
$success = $sse->LoadEvent($eventStr);
if ($success != 1) {
print "Failed to load sse event: " . $eventStr . "\r\n";
}
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 != 1) {
print "Failed to apply event: " . $sse->eventName() . ": " . $sse->data() . "\r\n";
}
else {
print "Successfully applied event: " . $sse->eventName() . ": " . $sse->data() . "\r\n";
}
}
}
$count = $count + 1;
}
# Make sure the background task is cancelled if still running.
$task->Cancel();
# Examine the JSON database after applying events..
$jsonDb->put_EmitCompact(0);
print "----" . "\r\n";
print $jsonDb->emit() . "\r\n";