Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

HTTP_Client connect to remote site (working code)

2018-10-18
2018-11-07
  • tjarcoboerkoel - 2018-10-18

    Dear reader,

    I've implemented a HTTP web client for requesting info from public online services.
    As test I'm able to connect to the webserver of a local LAN device and retrieve its webpage by sending a HTTP GET header, works fine.

    Then I tried to connect to a public weather service on apixu.com by setting up a TCP connection to its webserver on 94.237.49.36 port 80.
    But on the public service the code times-out after hanging in the "connecting" state for 5 seconds and never gets connected.

    Is there a route or firewall rule that I need to set?

    The M251 controller interface is configured correctly :
    IP : 192.168.2.5
    Subn : 255.255.255.0
    Gateway: 192.168.2.254 (ISP modem)
    Controller : M251
    Somachine : 4.1 SP2 (codesys 3.5.3)
    TCP lib used: TcpUdpCommunication (Schneider electric)

    Best regards,

     
  • dFx

    dFx - 2018-10-19

    DNS settings ?
    Gateway allows your PLC to ask for a unknown IP, but not for a name.
    If you use a url with a name (ex: google.com) then it needs to be resolved by a DNS server.
    Use your ISP DNS one or google's one (primary 8.8.8.8, secondary 8.8.4.4)

    Http should correctly passthrough your ISP router.
    Maybe you need a proxy configuration ?
    Check it from a computer accessing internet on the same router.

    Last but not least, start by issuing a ping (from your plc) to check if the service is available.

     
  • tjarcoboerkoel - 2018-10-22

    Hi,

    Thnx for your reply.
    No I connect to the IP directly and setup the HOST name in the HTTP header.
    So, I don't need the DNS.

    I am able to connect to the IP from a computer using Putty (Raw TCP) and when I send the content of the HTTP header I DO get the response form the webserver.

    This does not work form the controller, while when I connect to a local webserver it does work.

    I just can;t connect to a public IP-address.

     
  • dFx

    dFx - 2018-10-25

    tjarcoboerkoel hat geschrieben:
    […] and setup the HOST name in the HTTP header.[…]

    Could you detail this ? (I'm not familliar with HTTP)

     
  • tjarcoboerkoel - 2018-11-07

    Hi,

    Oke well I found the bug. The HTTP protocol is very strict and needs multiple CR+LF characters.
    So, for the people who need an HTTP header for simple GET requests.
    You may split up the url into document and arguments, but I didn't need that.

    FUNCTION_BLOCK HttpHeader
    VAR_INPUT
       URL         : STRING[255]    :='/data.xml?arg1=1&arg2=John' ;  
       HOST         : STRING[255]   :='subdomain.domain.org'; 
    END_VAR
    VAR_OUTPUT
       HttpReq       : ARRAY[1..255] OF BYTE;  //Might be changed to a pointer to write to
       HttpReqSize    : UDINT            := 0;            //Size of data in HttpReq       
    END_VAR
    VAR   
       sHttpReq   : STRING[255];
    END_VAR
    StrToLowerA( ADR(URL) );      //convert to lowercase characters
    StrToLowerA( ADR(HOST) );      //convert to lowercase characters
     
    sHttpReq := Standard.CONCAT('GET ', URL);
    sHttpReq := Standard.CONCAT(sHttpReq , ' HTTP/1.1$0D$0A');
    sHttpReq := Standard.CONCAT(sHttpReq , 'Host: ');
    sHttpReq := Standard.CONCAT(sHttpReq , HOST);
    sHttpReq := Standard.CONCAT(sHttpReq , '$0D$0A');  //first CR+LN
    sHttpReq := Standard.CONCAT(sHttpReq , '$0D$0A');  //second CR+LF (indicates end of feed)
    HttpReqSize := DINT_TO_UINT(StrLenA( ADR(sHttpReq) ) );
    HttpReq      := String_TO_ArrayOfByte(sHttpReq, TRUE);
    

    Just open a TCP connection to the servers IP where it's hosted at port 80, TCP_send the HttpReq and TCP_read back data (may take some time for the server to respond >500ms).
    You may read twice, because the server will first send the 400 OK header, followed by the requested data/page/file/...
    The Server will shutdown the connection when it's finished (and you know all data has been transferred).

     

Log in to post a comment.