Problems using core as client

I am trying to get my core to call a url when it starts.

To do that I am using this code

TCPClient client;
char url[] = "http://server.com";
char initReq[] = "GET /folder/file.php";
int port = 80;

void setup()
{
   //Register our Spark function here
   Spark.function("SWITCH", pinSwitch);
   
    if(client.connect(url, port))
    {
        String request = initReq + String("?spark=") + Spark.deviceID();
        client.println(request);
        client.print("HOST: ");
        client.println(url);
        client.println("Connection: close");

        client.println();
        client.flush();
    }
}


void loop()
{
   // Nothing to do here
}


int pinSwitch(String command)
{
   int state = 0;
   //find out the pin number and convert the ascii to integer
   int pinNumber = command.charAt(1) - '0';

   //Sanity check to see if the pin numbers are within limits
   if (pinNumber < 0 || pinNumber > 7)
   {
       return -1;
   }

   // find out the state of the led
   if(command.substring(3,7) == "HIGH")
   {
       state = 1;
   }
   else if(command.substring(3,6) == "LOW")
   {
       state = 0;
   }
   else
   {
       return -2;
   }

   // write to the appropriate pin
   pinMode(pinNumber, OUTPUT);
   digitalWrite(pinNumber, state);
   return 1;
}

But it does not seem to work, the url it calls should look like

http://server.com/folder/file.php?spark=00f00000000000000000

Can anyone spot the problem?

Hi,

TCPClient provides you with a raw TCP connection, so a URI will not work.

You will have to implement a basic HTTP client on top of TCPClient to make a GET request.

You have part of that implemented (Host: Connection: headers) but you’re missing HTTP/1.1 after your URI. It also needs to be terminated with “\r\n\r\n”

The request should be constructed like the following after establishing a TCP connection with the web server.

GET /folder/file.php?spark=abcd HTTP/1.1\r\n
Host: server.com\r\n
Connection: close\r\n
\r\n

Cheers,
Matt

1 Like

Tried this

TCPClient client;
byte server[]  = { 000, 000, 000, 000 };

void setup()
{
   //Register our Spark function here
   Spark.function("SWITCH", pinSwitch);
   
   
   if (client.connect(server, 80))
   {
        String tsData = String(Spark.deviceID());

        client.println("GET /folder/file.php?spark=" + tsData + " HTTP/1.1\r\n");
        client.println("Host: server.com\r\n");
        client.println("Connection: close\r\n");
        client.println("\r\n");

        client.flush();
        client.stop();
    }
}

but it still didn’t work, didn’t I make it up as you said?

Problem found

TCPClient client;
byte server[]  = { 000, 000, 000, 000 };

void setup()
{
   //Register our Spark function here
   Spark.function("SWITCH", pinSwitch);


   if (client.connect(server, 80))
   {
        String tsData = String(Spark.deviceID());

        client.println("GET /folder/file.php?spark=" + tsData + " HTTP/1.1");
        client.println("Host: server.com");
        client.println("Connection: close");
        client.println("");

        client.flush();
        client.stop();
    }
}

this works :slight_smile: I am using println so the \r\n seems to be inserted already.

1 Like

actually… it seems to work once, second time it tries it hangs somewhere in that code, and is not downloading new code…

It works exactly 2 times, 3rd time it hangs somewhere in this code

unsigned long lastSync = 0;
void nodeSync()
{
    if (millis() - lastSync < 60000 && lastSync != 0) return;
    
    pinMode(D7, OUTPUT);
    
    
    lastSync = millis();
    
    if (client.connect(server, 80))
    {
        digitalWrite(D7, HIGH);
        String tsData = String(Spark.deviceID());

        client.println("GET /folder/file.php?spark=" + tsData + " HTTP/1.1");
        client.println("Host: server.com");
        client.println("Connection: close");
        client.println("");

        client.flush();
        client.stop();
    }
    
    digitalWrite(D7, LOW);
}

This seems to work!

unsigned long lastSync = 0;
void nodeSync()
{
    if (millis() - lastSync < 60000 && lastSync != 0) return;
    lastSync = millis();
    
    pinMode(D7, OUTPUT);
    
    if (client.connect(server, 80))
    {
        digitalWrite(D7, HIGH);
        String tsData = String(Spark.deviceID());

        client.println("GET /folder/file.php?spark=" + tsData + " HTTP/1.1");
        client.println("Host: server.com");
        client.println("Connection: close");
        client.println();
        
        while (client.available()) //Read what is returned from the server
        {
            char c = client.read();
            if (millis() - lastSync > 500) continue; //Read for maximum 500ms, then continue
        }

        client.flush();
        client.stop();
    }
    
    digitalWrite(D7, LOW);
}

after having it read a bit from what is returned, it seems to no longer lock up

1 Like

@Mikey Do you mean, “break” or “continue” ?? Because ‘continue’ would let the loop carry on right?

And as far I’ve tried the longer it takes to read characters from the Client or from a Server, the chances of it hanging up are higher. Thanks for that :smile:

Yes, you are right… brainfart there xD

Hi @Mikey is the TCP client working for you as today?
My tcp client was working fine but I can’t get it to work today…very weird…

I first got back to using it today, and I can’t get it to work at all.

I see the led changing, which means it goes into the function where it connects to my server and sends the data, but my server does not receive anything, and the led changes back to breathing again right away too.

The code I am using is something I have used before, but it does not seem to work any longer.

With http requests from the core, I think putting a short delay delay(100) after your client.stop() can help make things more consistent. Lemme know if that works!

Thanks,
David

That does not seem to do it either.

My code is this

unsigned long lastSync = 0;
void nodeSync()
{
    if ((millis() - lastSync < 3600000  && lastSync != 0) && millis() >= lastSync) return; //Only check once every hour, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
    lastSync = millis();
    
    RGB.control(true);
    
    TCPClient client;
    byte server[]  = { xxx, xxx, xxx, xxx };
    
    if (client.connect(server, 80))
    {
        RGB.color(255, 0, 0);
        String tsData = String(Spark.deviceID());

        client.println("GET /folder/file.php?spark=" + tsData + " HTTP/1.1");
        client.println("Host: server.com");
        client.println("Connection: close");
        client.println();
        
        while (client.available()) //Read what is returned from the server
        {
            char c = client.read();
            if (millis() - lastSync > 500) break; //Read for maximum 500ms, then stop reading
        }

        client.flush();
        client.stop();
        delay(100);
    }
    
    RGB.control(false);
}

and I see the led change to red, then back to breathing again, but the server does not seem to get anything.

@Mikey Are you uploading the code from the Web IDE or locally? If you’re doing it locally can you try using the latest firmware.

Also maybe you could try to reduce your interval of HTTP requests from 1 hour to say 10 seconds and see if your server picks up at least a few of the many requests you are sending.

I’m highly uncertain about this but I see a tiny problem within the code (Please correct me if I’m wrong). You seem to be creating a new ‘tcpClient’ object inside every call to the function ‘nodeSync’. I wonder if this might be causing the core to run into problems with the number of sockets opened.

2 Likes

@nitnut, I am uploading from web. I have tried to set it down, and leave it there for a while, didn’t work either.

I have also tried to define tcpclient outside, didn’t work either.

Tried to have a look in the apache log, and it looks like something is getting through now, however it seems to return status code 400 (Bad Request) so looks like it is trying to get hold of a wrong host maybe?

Not sure if your webserver is set to respond to “server.com” or if you replaced the hostname in your code, but often webservers aren’t configured to do wildcard hosting. Maybe make sure to change “server.com” to match what your server thinks its hostname is?

@Mikey Two things.

Firstly, I had faced issues with client.println() the other day when I was doing non-http tcp requests to server at port 8888. When I used client.write(buff, length) it worked fine. However do this as a last resort since almost everyone is using client.println() successfully.

Secondly and more likely, I think you are closing the connection before you get a TCP Response back from the server. Usually when a browser/app/script makes a TCP request, there’s a timeout/wait period of 2-10 seconds before the client closes the connection.

So you could probably include the following before you do your while(client.available()) :

unsigned long timeoutTimer = millis();
while(millis() - timeoutTimer < 2000){
  if(client.available()){
    break; // received response from server - stop waiting
  }
}

while(client.available())... YOUR CODE Continues

Hope that helps :smile:

I got some code from someone else that works, still trying to figure out why mine suddenly stopped to work.

“server.com” was configured correctly, checked it many times to make sure, then checked it a few extra times.

1 Like