Hey There Photonators,
Like many of you I’m developing a product that needs a fluid user experience.
I’m having an issue with 5 second timeouts with the photon when TCPClient.connect is unable to connect in the case of a bad IP, or a non listening server that is killing my UX. I know the company is going through growing pains but to have a TCPClient on a WiFi product that does not have a good a robust interface is pretty disappointing.
With derivations of the following code I observe the following connection cases:
Case 1: TCP Connect
- W/ Server Listening No Issue
- W/o Server Listening 5 second hang
- Bad IP 5 second hang
Case 2: WiFi Ping Default Retry of 5
- W/ Server Listening No Issue
- W/o Server Listening No Issue
- Bad IP 5 second hang
Case 3: WiFi Ping Retry of 1
- W/ Server Listening No Issue
- W/o Server Listening No Issue
- Bad IP 1 Second Hang
I think i’ve seen this issue in a few other threads, but I’d really like to find a working solution for products that will be in a variety of different Wireless Environments, and encourage finding a long term solution that adds value rather than takes away value
A 1 Second Delay is alot better than 5 Seconds for my application but it seems arbitrary and long.
Could the same code that causes ping() to default to a 5 second delay cause a TCP.connect() to also be 5 seconds? Can this be reduced, or can control be given to the user to choose the timeout?
Maybe this is an issue that can be avoided all together through clever application code? Has anyone solved this problem and come up with a fluid connection routine?
Nearly at my whits end here and pretty frustrated any help or wisdom would be much appreciated
//adapted from @Hootie81 & @jon1977 in community.particle.io
#include "application.h"
//#include "dnsclient.h"
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD( ENABLED );
int serverPort = 8330;
uint32_t lastTime;
const char replymsg[60] = "TheInMsg and then a whole lot more characters than before";
String clientmsg = String("mymsg 2 and then a whole lot more characters than before");
char inmsg[512];
String myInStr;
char myIpString[24];
//IPAddress server(192, 168, 1, 80);//server's ip address
char * server = "playbeemo.com";
IPAddress serverIP;
IPAddress pingGoogle(8,8,8,8);
IPAddress pingBad(169,254,0,0);
bool complete;
TCPClient client;
//DNSClient dns;
bool initialConnection = false;
char outmsg[50];
void setup()
{
Serial.begin(115200);
pinMode(D6,OUTPUT);
pinMode(D7,OUTPUT);
pinMode(D3,INPUT);
delay(1000);
while(!Serial.available()){Particle.process();}
log("Serial Connected");
while (!WiFi.ready()) {
log("Wifi Not Ready...");
Particle.process();
WiFi.connect();
while(WiFi.connecting()) {Particle.process();}
}
log("Wifi Now Ready...");
log("Resolve Server IP...");
serverIP = WiFi.resolve( server );
log("Got: " + String(serverIP));
//log("Starting DNS Server");
//log("DNS IP: "+ String(WiFi.dhcpServerIP()));
//dns.begin(dnsServerIP);
}
void loop() {
log("---------GO LOOP-------");
pingIPs();
log("Calling Open:");
open();
log("Checking If Connected");
if (initialConnection && client.connected()) {
lastTime = millis();
get();
}
log("Calling Close:");
close();
log("---------END LOOP-------");
log("\r\n\r\n\r\n\r\n\r\n");
delay(5000);
}//loop
void log(String message){
//Super Debug Mode Will Try Both Serial And WiFi-zle if it's turn
//We will default to serial always for zeee robust debugging
Serial.print(millis());
Serial.print("|^|\t");
Serial.println(message);
if ( initialConnection ){
client.print(millis());
client.print("|^|\t");
client.println(message);
}
}
void pingIPs(){
//delay(1000);
int rtryCount = 1;
log("Pinging with rtry Count "+String(rtryCount));
int rpingGate = WiFi.ping(serverIP,rtryCount);
log("Ping Beemo: "+ String(rpingGate));
//delay(1000);
int rpingGoog = WiFi.ping(pingGoogle,rtryCount);
log("Ping Google: "+ String(rpingGoog));
//delay(1000);
int rpingBad = WiFi.ping(pingBad,rtryCount);
log("Ping Bad: "+ String(rpingBad));
}
void open(){
log("Trying To Connect...");
initialConnection = client.connect( server, serverPort);
if (initialConnection) {
log("Got Connected...");
}
else{
log("Not Connected...");
}
}
void close(){
log("Stopping Client");
if (initialConnection){
log("Closing...");
client.stop();
log("Closed");
}
}
void get(){
while ((!client.available()) && (millis() - lastTime < 1)) {
//Particle.process();
log("Client Not Available");
}//wait for response
log("Get Msg");
in(inmsg,10);//5-10 pure trial and error
log("Got: ");log(inmsg);
}
void in(char *ptr, uint8_t timeout) {
int pos = 0;
unsigned long lastdata = millis();
while ( client.available() || (millis()-lastdata < timeout)) {
if (client.available()) {
char c = client.read();
lastdata = millis();
ptr[pos] = c;
pos++;
}//if (client.available())
}//while ( client.available() || (millis()-lastdata < timeout))
client.read();
}//void in(char *ptr, uint8_t timeout)