Closed mars000 closed 4 years ago
It's not different in term of operation between that functions.
The time consumed for operation based on the network situation.
The client should take care of and wait for the server response to be finished with the timeout to ensure the success of the request.
The time consuming then vary depending on the time used in request , response and SSL/TLS handshake.
If you are using different Firebase Data object for streaming and reading/storing data, the connection between server and client is kept alive and the time consuming for the request and response will be significantly reduced (use approx. 200 - 300 ms per request).
thank you mobizt for the quick and helpful response.
A few questions:
My code below (modified from your ;-))
/*
* Created by K. Suwatchai (Mobizt)
*
* Email: k_suwatchai@hotmail.com
*
* Github: https://github.com/mobizt
*
* Copyright (c) 2020 mobizt
*
* This example is for the beginner
*
*/
#include <WiFi.h>
#include <FirebaseESP32.h>
#include <Ticker.h>
//1. Change the following info
#define FIREBASE_HOST "https://esp32-flutter-firebase-ec9c6.firebaseio.com/"
#define FIREBASE_AUTH "xxxxx"
#define WIFI_SSID "xxx"
#define WIFI_PASSWORD "xxx"
Ticker sendMessage1;
Ticker sendMessage2;
//Debug Blynk to serial port
#define BLYNK_PRINT Serial
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
//Auth token for your Blynk app project
#define BLYNK_AUTH "YOUR_BLYNK_APP_PROJECT_AUTH_TOKEN"
//Define FirebaseESP32 data objects
FirebaseData firebaseData0;
FirebaseData firebaseData1;
FirebaseData firebaseData2;
FirebaseData firebaseData3;
String path0 = "/Blynk_Test";
String path = "/Blynk_Test/Int";
String path1 = "/Blynk_Test/String";
//D4 or GPIO2 on Wemos D1 mini
uint8_t BuiltIn_LED = 2;
void printResult(FirebaseData &data);
void printResult(StreamData &data);
/*
Blynk app Widget setup
**********************
1. Button Widget (Switch type), Output -> Virtual pin V1
2. LED Widget, Input -> Virtual pin V2
*/
WidgetLED led(V4);
void streamCallback1(StreamData data)
{
Serial.println("Stream Data [1] available...");
Serial.println("STREAM PATH: " + data.streamPath());
Serial.println("EVENT PATH: " + data.dataPath());
Serial.println("DATA TYPE: " + data.dataType());
Serial.println("EVENT TYPE: " + data.eventType());
Serial.print("VALUE: ");
printResult(data);
Serial.println();
}
void streamCallback0(StreamData data)
{
Serial.println("Stream Data [0] available...");
Serial.println("STREAM PATH: " + data.streamPath());
Serial.println("EVENT PATH: " + data.dataPath());
Serial.println("DATA TYPE: " + data.dataType());
Serial.println("EVENT TYPE: " + data.eventType());
Serial.print("VALUE: ");
printResult(data);
Serial.println();
}
void streamTimeoutCallback(bool timeout)
{
if (timeout)
{
Serial.println();
Serial.println("Stream timeout, resume streaming...");
Serial.println();
}
}
void setup()
{
Serial.begin(115200);
pinMode(BuiltIn_LED, OUTPUT);
WiFi.begin("xxx", "xxx);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
if (!Firebase.beginStream(firebaseData1, path))
{
Serial.println("------------------------------------");
Serial.println("firebase1 -> Can't begin stream connection...");
Serial.println("REASON: " + firebaseData1.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
if (!Firebase.beginStream(firebaseData0, path0))
{
Serial.println("------------------------------------");
Serial.println("firsbase0 -> Can't begin stream connection...");
Serial.println("REASON: " + firebaseData0.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
Firebase.setStreamCallback(firebaseData1, streamCallback1, streamTimeoutCallback);
Firebase.setStreamCallback(firebaseData0, streamCallback0, streamTimeoutCallback);
// auth = garage gate
Blynk.config("xxx", "blynk.xxx.com", 80);
Blynk.connect();
}
void loop()
{
Blynk.run();
/* if (!Firebase.readStream(firebaseData1))
{
Serial.println("------------------------------------");
Serial.println("firebaseData1 -> Can't read stream data...");
Serial.println("REASON: " + firebaseData1.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
if (!Firebase.readStream(firebaseData0))
{
Serial.println("------------------------------------");
Serial.println("firebaseData0 -> Can't read stream data...");
Serial.println("REASON: " + firebaseData0.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
if (firebaseData1.streamTimeout())
{
Serial.println("Stream timeout, resume streaming...");
Serial.println();
}
if (firebaseData1.streamAvailable())
{
Serial.println("------------------------------------");
Serial.println("Stream Data available...");
Serial.println("STREAM PATH: " + firebaseData1.streamPath());
Serial.println("EVENT PATH: " + firebaseData1.dataPath());
Serial.println("DATA TYPE: " + firebaseData1.dataType());
Serial.println("EVENT TYPE: " + firebaseData1.eventType());
Serial.print("VALUE: ");
if (firebaseData1.dataType() == "int")
{
Serial.println(firebaseData1.intData());
if (firebaseData1.intData() == 0)
{
Blynk.virtualWrite(V11, LOW);
// led.off();
}
else if (firebaseData1.intData() == 1)
{
Blynk.virtualWrite(V11, HIGH);
// led.on();
}
}
}
if (firebaseData0.streamAvailable())
{
Serial.println("------------------------------------");
Serial.println("Stream Data available...");
Serial.println("STREAM PATH: " + firebaseData0.streamPath());
Serial.println("EVENT PATH: " + firebaseData0.dataPath());
Serial.println("DATA TYPE: " + firebaseData0.dataType());
Serial.println("EVENT TYPE: " + firebaseData0.eventType());
Serial.print("VALUE: ");
if (firebaseData0.dataType() == "int")
{
Serial.println(firebaseData0.intData());
if (firebaseData1.intData() == 0)
{
Blynk.virtualWrite(V11, LOW);
// led.off();
}
else if (firebaseData0.intData() == 1)
{
Blynk.virtualWrite(V11, HIGH);
// led.on();
}
}
if (firebaseData0.dataType() == "string")
{
Serial.println(firebaseData0.stringData());
}
if (firebaseData0.dataType() == "json")
{
FirebaseJson &json = firebaseData0.jsonObject();
//Print all object data
Serial.println("Pretty printed JSON data:");
String jsonStr;
json.toString(jsonStr, true);
Serial.println(jsonStr);
// }
Serial.println("------------------------------------");
Serial.println();
} */
}
BLYNK_WRITE(V11)
{
static bool already_called = false;
static int counter = 0;
int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
if (pinValue == 0)
{
led.off();
already_called = false;
}
if (pinValue == 1)
{
led.on();
if (already_called == false)
{
Serial.println("------------------------------------");
Serial.println("Set integer...");
//Also can use Firebase.set instead of Firebase.setInt
if (Firebase.setInt(firebaseData2, path, pinValue))
{
Serial.println("int PASSED");
Serial.println("PATH: " + firebaseData2.dataPath());
Serial.println("TYPE: " + firebaseData2.dataType());
Serial.print("VALUE: ");
if (firebaseData2.dataType() == "int")
Serial.println(firebaseData2.intData());
Serial.println("------------------------------------");
Serial.println();
already_called = true;
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData2.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
Serial.println("Set string..");
String mess = "Pressed @ " + String(millis());
if (Firebase.setString(firebaseData3, path1, mess))
{
Serial.println("String PASSED");
Serial.println("PATH: " + firebaseData3.dataPath());
Serial.println("TYPE: " + firebaseData3.dataType());
Serial.print("VALUE: ");
if (firebaseData3.dataType() == "string")
Serial.println(firebaseData3.stringData());
Serial.println("------------------------------------");
Serial.println();
already_called = true;
}
else
{
Serial.println("FAILED");
Serial.println("REASON: " + firebaseData2.errorReason());
Serial.println("------------------------------------");
Serial.println();
}
}
}
}
void printResult(StreamData &data)
{
if (data.dataType() == "int")
Serial.println(data.intData());
else if (data.dataType() == "float")
Serial.println(data.floatData(), 5);
else if (data.dataType() == "double")
printf("%.9lf\n", data.doubleData());
else if (data.dataType() == "boolean")
Serial.println(data.boolData() == 1 ? "true" : "false");
else if (data.dataType() == "string" || data.dataType() == "null")
Serial.println(data.stringData());
else if (data.dataType() == "json")
{
Serial.println();
FirebaseJson *json = data.jsonObjectPtr();
//Print all object data
Serial.println("Pretty printed JSON data:");
String jsonStr;
json->toString(jsonStr, true);
Serial.println(jsonStr);
Serial.println();
Serial.println("Iterate JSON data:");
Serial.println();
size_t len = json->iteratorBegin();
String key, value = "";
int type = 0;
for (size_t i = 0; i < len; i++)
{
json->iteratorGet(i, type, key, value);
Serial.print(i);
Serial.print(", ");
Serial.print("Type: ");
Serial.print(type == FirebaseJson::JSON_OBJECT ? "object" : "array");
if (type == FirebaseJson::JSON_OBJECT)
{
Serial.print(", Key: ");
Serial.print(key);
}
Serial.print(", Value: ");
Serial.println(value);
}
json->iteratorEnd();
}
else if (data.dataType() == "array")
{
Serial.println();
//get array data from FirebaseData using FirebaseJsonArray object
FirebaseJsonArray *arr = data.jsonArrayPtr();
//Print all array values
Serial.println("Pretty printed Array:");
String arrStr;
arr->toString(arrStr, true);
Serial.println(arrStr);
Serial.println();
Serial.println("Iterate array values:");
Serial.println();
for (size_t i = 0; i < arr->size(); i++)
{
Serial.print(i);
Serial.print(", Value: ");
FirebaseJsonData *jsonData = data.jsonDataPtr();
//Get the result data from FirebaseJsonArray object
arr->get(*jsonData, i);
if (jsonData->typeNum == FirebaseJson::JSON_BOOL)
Serial.println(jsonData->boolValue ? "true" : "false");
else if (jsonData->typeNum == FirebaseJson::JSON_INT)
Serial.println(jsonData->intValue);
else if (jsonData->typeNum == FirebaseJson::JSON_DOUBLE)
printf("%.9lf\n", jsonData->doubleValue);
else if (jsonData->typeNum == FirebaseJson::JSON_STRING ||
jsonData->typeNum == FirebaseJson::JSON_NULL ||
jsonData->typeNum == FirebaseJson::JSON_OBJECT ||
jsonData->typeNum == FirebaseJson::JSON_ARRAY)
Serial.println(jsonData->stringValue);
}
}
}
1. As I post above you need (essential) to take care of the request response. Non block for server request in not make sense and useless. You can use async or non block for server side but the client should wait for complete response.
If you implement your own the tcp/udp server communication, you can implement non block on your client side but no guarantee of packet received ordering sequence and the lost of packets.
2. It's not the web socket. it is the http request on secure port (443) sent to sever with the header that the connection should keep alive and server should not close it after sent the response. The connection is kept alive as long as both client and server are on the internet.
I have answered this in many opened issues and also wrote the comment in the stream examples for long time.
If you've found the unacceptable latency or network round trip delay in your device, the problem may be at the router or AP.
thanks for your answers - they assist a great deal in my understanding how to best use your very useful library.
thanks for pulling together a great library. Wonder - why is it (at startup especially) it can take 2-3 times longer to do a setString vs setInteger ? what is going on under the hood.
Also - any way to make setString, setInt non blocking ?
kind regards