Wifi and UC5550

I’m working on a small project with distributed sensors and actuators. The main unit is a custom Raspberry CM3+ board, running a net core webapi logging to a sql server and manging other stuff. The peripheral sensors and actuators are a TinyCLR devs. I’m prototyping with UC5550+ wifi and Fez wifi.
Mainly it can works, and I can post to webapi data via wifi SPW04 calls.
I’m probably making something wrong with my code, becouse I can send only 8 calls to webapi. Probably it leaves open underlaying socket. I’ve stripped down the code to test:

        string resps = "";
        // simulate sensor packet...
        var reqjson = $@"{{
                            'message': 'Device Ok: 60',
                            'ioT_Device': 'TINYCLR1',
                            'iotDate': '{DateTime.Now:yyyy-MM-ddTHH:mm:ss}',
                            'sensor1': 59.215686274509807,
                            'sensor2': 22.805429864253391,
                            'sens_power': 0
                        }}";
using (HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://" + host + ":" + port + url ))
                {
                    
                    var jbuf = Encoding.UTF8.GetBytes(reqjson);
                    httpWebRequest.Method = "POST";
                    httpWebRequest.ContentType = "application/json";
                    httpWebRequest.ContentLength = jbuf.Length;
                    
                    Stream sreq = httpWebRequest.GetRequestStream();
                    sreq.Write(jbuf, 0, jbuf.Length);
                    //sreq.Flush();
                    //sreq.Close();
                    var resp = httpWebRequest.GetResponse();
                    Stream s = resp.GetResponseStream();
                    using (StreamReader srd = new StreamReader(s))
                    {
                        resps = srd.ReadToEnd();
                    }
                    //resps = Encoding.UTF8.GetString(buffer);
                    //s.Flush();
                    //s.Close();
                    resp.Close();
                    
                };

Using this code the call is working fine, but only for 8 calls (I suppose 8 [0 to 7] is max open socket allowed). How I can close the underlaying socket? SPW04 driver can return actual call socket?

Just to test, can you use the HTTP API on the SPWF04 interface itself, instead of the .NET HTTP API? To see if there’s a bug in the .NET HTTP library that doesn’t close sockets.

Hi John,
Sure I can do it.
But how I can send a payload (json string, see above) via POST using SPW04 SendHttpPost call?

Ah, right. Sorry. That command only supports payload from a file. You’ll have to use the socket API on the driver instead constructing the HTTP headers yourself.

You can actually inspect the web request object from your code for the header collection so you can just mirror that.

Ok, I will take a look at the low level driver if I can get some clue.
I’m sure that underlaying sockets are not closed after the call ends, using my code above.

Using the SendHttpGet() call it works fine and no problem with sockets.

1 Like

WIND: PendingData :0:165:165
WIND: PendingData :0:5:169
HTTP 0 - {“id”:“307”}

Read: 0 in 5,408ms
163,088
WIND: PendingData :1:165:165
WIND: PendingData :1:5:170
HTTP 0 - {“id”:“308”}

Read: 0 in 3,034ms
170,656
WIND: PendingData :2:170:170
HTTP 0 - {“id”:“309”}

Read: 0 in 3,099ms
174,416
WIND: PendingData :3:165:165
WIND: PendingData :3:5:170
HTTP 0 - {“id”:“310”}

Read: 0 in 3,040ms
178,240

Using post via .NET, the PendingData indication report an incrementing number x (in the format :x:y:z). When x > 8 then program get stuck on the GetResponse() call. Strange enough, it seems that there are pending data after each call, but the response data have got correctly from the server {“id”:“310”} .

1 Like

Do you have a public url you can verify against so we can test on our end?

Hi John,
Oh I can publish a (very) basic test version on a public server if you want test against a webapi post … that’s not a problem.
I opened a firewall port for api calls. The urls is http://bd.ledonet.com:9080 or https://bd.ledonet.com:9443
This is a IIS virtual server and cert for SSL is auto signed (I don’t know if usable with TinyCLR TLS, due to root cert not valid).
Api call URI is:
http://bd.ledonet.com:9080/api/values
If GET this url you get back 10 records in json format, if you POST a record in json format in the body (see code above) it returns an {‘id’:‘xxxx’} (where xxxx is an int number) json string if success, otherwise { ‘error’ : ‘[error description]’}.
Using:
http://bd.ledonet.com:9080/api/values/xxxx you get back single record of id xxxx in json format

Due to constant hacker presence on the internet, advice me when I can close ports :wink:

So putting your above code in our test program, on most test runs it ran fine. It continually reads all data over HTTP and closes the socket, all on socket 0. On one run however, the sockets weren’t closing. Letting it sit for a while though the sockets did eventually all close with the result Shown when Remote TCP sent a RST, or did not rely to FINACK.

Do you have a complete program you can send that we can try to run here with no changes (except SSID and WiFi password)? Also, try posting to another server completely. There are free ones that just echo back what you send available hosted online. If you let the program sit for a while do you get any WINDs saying the sockets are closing? Based on the error I got, I think one possible explanation is that the socket close process isn’t working properly so they get left half open.

1 Like

@John_Brochue thank you, very kind to test the code!!
I’ll setup fiddler and/or wireshark to see what’s happening. Running the server webapi code hosted in IIS, it is working fine mostly as you say.
If I host webapi in the Kestrel .Net core server, achhh, it is not FINACKing calls with POST…
Damned MS guys… I will deep better in the Kestrel options (may be keepalive). I confirm that SocketClose WIND message appear after timeout running against the Kestrel server.
I will check …

A little follow-up: I’ve tested same webapi server code in .Net core 2.2.4 and I found that TinyCLR keep going only if the server is IIS hosted, but it locks on Kestrel hosted (arm or x86 same result). I have done clients for Win, Mac, Linux (x86 and ARM) and they have no problem at all running for hours using both IIS and Kestrel embedded server, with correct open/close socket sequence (I could check context connection underlayer). I couldn’t find any config option to solve the issue with Tinyclr/Kestrel. In TinyCLR the WebRequest.Timeout prop doesn’t unlock the GetResponse().

Were you able to find anything with Wireshark or Fiddler around the socket closes with Kestrel?

I hope to have some spare time after Easter day to spend on the topic … But I’m really courious to understand the issue…