FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
03-07-2023 12:55 AM
I am using the WebClient FB of the IIoT library. When using urls with the domain name instead of the IP address, the function block contacts the DNS (Domain Name Server) to resolve the IP address. However, if the DNS is not reachable, the WebClient functionblock gets blocked for a certain amount of time. On my ctrlX node for 10s, on another ctrlX I have seen 20s. The task that is running the functionblock stops running while the functionblock is blocked. The issue can be reproduced by:
Use a 1:1 connection between the engineering PC and the ctrlX XF10 (no other connections on the ctrlX)
Manually configure a DNS server, the IP adress should not be the same as the ctrlX or the engineering PC
Send out an request through the WebClient function block, e.g. https://www.boschrexroth.com/
The function block gets stuck for 10 and then generates an error and shows RESOLVE_HOSTNAME_FAILED.
For the exampe below the task shows a max cycle time of 10001583us ~= 10s
There are two issues here:
The timeout of the request is not determined by the timeout of the functionblock (above the timout is set to 3s, the functionblock was blocked for 10s)
The functionblock stops its task from running, stopping all logic in the task from executing
Solved! Go to Solution.
03-28-2023 01:16 PM
Hello,
We apologize for the late response.
An optimization is planned here: Web Client SL: Replace SysSockGetHostByName in Web_Client FB by ResolveHostname.
This is, what we received as a possible work around:
Before calling the WebClient FB, the user could use a ResolveHostname FB from the Net Base Services library asynchronously to check whether the host name can be resolved. Thus whether the DNS server can be reached and only call the WebClient FB if the DNS server can be reached.
Declaration:
asyncProperty : NBS.AsyncProperty := (anAppName := 'Application', tgTaskGroup := 'IEC-Tasks', tnTaskName := 'xxx', udiTaskInterval := 20000 , usiTaskPrio := 20);
ip: NBS.IIPAddress;resolve: NBS.ResolveHostname := (itfAsyncProperty := asyncProperty, sHostname := sHostname, udiTimeout := 1000000);
Implementation:
resolve(xExecute := TRUE, itfIPAddress := ip);
03-28-2023 10:33 PM
This workaround will avoid the task being blocked. However, I am not able to get the IP address through the NBS.ResolveHostname. My plan was something like this (simplified code example):
Declaration
VAR
hostname: STRING := 'www.codesys.com';
url: STRING;
asyncProperty: NBS.AsyncProperty := (anAppName := 'Application', tgTaskGroup := 'IEC-Tasks', tnTaskName := 'bgTask', udiTaskInterval := 20000 , usiTaskPrio := 30);
ip: NBS.IIPAddress;
resolve: NBS.ResolveHostname := (itfAsyncProperty := asyncProperty, udiTimeout := 1000000);
webcl: WEB_CLIENT.WebClient;
END_VAR
Implementation
resolve(itfIPAddress := ip, sHostname := hostname);
IF resolve.xDone THEN
url := CONCAT('https://', ip.CompressedIP);
resolve.xExecute := FALSE;
webcl.xExecute := TRUE;
END_IF
webcl(sURL := url, eRequestType := WEB_CLIENT.REQUEST_TYPE.GET);
The ip.CompressedIP (in the url assignment line) gives me an exception. I do not understand how to get the IP address from the resolve FB.
04-03-2023 04:50 PM
Hello,
there is missing an instance to the interface IIPAddress.
The following should work:
Declaration:
VAR
hostname: STRING := 'www.codesys.com';
url: STRING;
asyncProperty: NBS.AsyncProperty := (anAppName := 'Application', tgTaskGroup := 'IEC-Tasks', tnTaskName := 'bgTask', udiTaskInterval := 20000 , usiTaskPrio := 30);
ipv4Address: NBS.IPv4Address;
itfIPAddress: NBS.IIPAddress := ipv4Address;
resolve: NBS.ResolveHostname := (itfAsyncProperty := asyncProperty, udiTimeout := 1000000);
webcl: WEB_CLIENT.WebClient;
END_VAR
Implementation:
resolve(xExecute := TRUE, itfIPAddress := itfIPAddress, sHostname := hostname);
IF resolve.xDone THEN
url := CONCAT('https://', ipv4Address.ipAddress);
webcl.xExecute := TRUE;
END_IF
webcl(sURL := url, eRequestType := WEB_CLIENT.REQUEST_TYPE.GET);