B4R Question Long delay before iOS browser gets first page from ESP server

BertI

Member
Licensed User
I am finding that it takes a long time for an iOS browser (e.g Safari on iOS 14.8) to get the first page from a basic ESP8266 server. Sometimes can take more than 30s or even not get it at all. Having stripped the code to pretty much the bare minimum and with some judicious logging I have noticed that the delay occurs between the time of initial connection (Server_NewConnection triggered) and the point at which the Astream_NewData is triggered. In fact it looks like iOS closes the connection and retries before success. See code below:
#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 3000
#End Region

Sub Process_Globals
'These global variables will be declared once when the application starts.
'Public variables can be accessed from all modules.
Public Serial1 As Serial
Public wifi As ESP8266WiFi
Public Astream As AsyncStreams
Public server As WiFiServerSocket
Public st As ULong
End Sub

Private Sub AppStart
st=Millis

Serial1.Initialize(115200)
Log("AppStart")
Log("after start time: ",Millis-st)

RunNative("SetSTA", Null)

Log("Before connect time: ",Millis-st)
If Not(wifi.IsConnected) Then wifi.Connect2("xyz","12345678")
Log("After connect time: ",Millis-st)

Log("IP: ",wifi.LocalIp)

server.Initialize(80, "Server_NewConnection")
server.Listen
Log("After server start time: ",Millis-st)

End Sub

Private Sub Server_NewConnection (NewSocket As WiFiSocket)
Log("NEW server CONNECTION ********** at: ", Millis-st)
Astream.Initialize(NewSocket.Stream, "astream_NewData", "astream_Error")
Astream.MaxBufferSize=1000
End Sub

Private Sub Astream_NewData (Buffer() As Byte)
Log("Astream Data -------------------------------------- ", Millis-st)
Log("Length: ",Buffer.Length,CRLF)
Log(Buffer)
Log(CRLF)
Log("Time: ",Millis-st)

Astream.Write("HTTP/1.1 200").Write(CRLF)
Astream.Write("Content-Type: text/html").Write(CRLF).Write(CRLF)
Astream.Write("Hello World").Write(CRLF)
CallSubPlus("CloseConnection",200,0)
End Sub

Private Sub AStream_Error
Log("Disconnected at Astream Error sub")
server.Listen
End Sub

Private Sub CloseConnection(u As Byte)
Log("close connection sub at: ", Millis-st)
If server.Socket.Connected Then
Log("server was connected")
server.Socket.Stream.Flush
server.Socket.Close
Else
Log("server was not connected")
End If
End Sub

#if C
void SetSTA(B4R::Object* o) {
WiFi.mode(WIFI_STA);
}
#end if
The typical log output from an attempted connection is:
after start time: 1
Before connect time: 3
After connect time: 5854
IP: 192.168.2.18
After server start time: 5858
NEW server CONNECTION ********** at: 31911
Disconnected at Astream Error sub
NEW server CONNECTION ********** at: 62219
Astream Data -------------------------------------- 62231
Length: 372
GET / HTTP/1.1
Host: 192.168.2.18
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1
Accept-Language: en-gb
Accept-Encoding: gzip, deflate
Connection: keep-alive
Time: 62270
close connection sub at: 62471
server was connected
Disconnected at Astream Error sub
Firefox from IOs device yields similar results. On the other hand if I try to connect to the same server using a browser on an Android device (native or Firefox) or from a LAN connected Windows PC, then the page is served up pretty much immediately.

I have had similar experiences with ESP32 devices

If I use AP mode and connect the iOS device to the ESP's AP then I don't seem to get this issue

Anyone have a clue?

Just add to my observations: The issue appears to occur only when the first connection from the browser is made. If I reload the page the server appears to respond to the next GET request very quickly. Even if I reset the ESP device but just click on reload page on the browser after the ESP has re-established the server, it still responds quickly. However if I close the browser down, restart it and then try and connect same long delay.
 
Last edited:

BertI

Member
Licensed User
Thanks for your quick response. When you say cellular network do you mean literally the entire mobile connection to the phone, or do you mean the data connection i.e 4G etc? The latter is off anyway (I don't tend to use this phone for data connections over the phone network). Tried switching that on and off but no difference to outcome.

The curious thing though is that the NewConnection process in the ESP code IS triggered almost immediately - just that it then takes a long time for any of the expected GET Data to be seen. It's almost as if the process which follows the initial socket connection is waiting for some kind of lower level acknowledge at the iOS end which it doesn't get, so a retry is then made by the client (I notice it is usually a 30s delay) and somehow on the second attempt something 'unblocks' and remains so until you close down the browser and start afresh. Or I suppose it could be that the process in the ESP which detects that there is data (or end of data) in the buffer isn't working correctly so doesn't trigger the Astream_NewData sub, so the latter then doesn't get the chance to send the response to the Get hence the client then retries?
 
Upvote 0

BertI

Member
Licensed User
Unfortunately I don't have access to B4i, but anyhow it's not that I want to create an app for accessing the ESP8266 server. What I want to be able to do is just allow the user to access the server via any browser.

I have tried a basic server example Arduino sketch (HelloServer). There was still some delay before it served up the page but this was a few seconds rather than 30. Still interesting that there was a delay at all compared to the almost immediate response when using a non iOS browser.

I also tried the B4R code with an iPad rather than the phone and still the same symptoms. I have tried a different router and not connected to the internet, i.e connecting both the iPhone and the ESP8266 via the isolated router. Still same issue.

What is also niggling me is - why haven't I seen reports from other people about this symptom? What can it be that I have different to anyone else?
 
Upvote 0

candide

Active Member
Licensed User
possible they try to connect in https first and after some errors they fallback to http.

also, you can try to connect to esp with webserver built with raWOT, you have several projects ready to test with library and you will see if it is similar
 
Upvote 0

BertI

Member
Licensed User
Thanks for your input candide. I downloaded your examples zip file but I couldn't find the raWOT library files? Must admit I did wonder if it was some kind of iOS security related behaviour, but wonder why iOS would try https when the url says http

The problem I have though is that I need to be able to create my own server code, so I need to understand why the fundamental B4R server socket connection followed by astream data collection is showing these symptoms.
 
Upvote 0

candide

Active Member
Licensed User
sorry, yes library raWOT was not in last zip with examples.( it seems you are the first downloading raWOT 😁)

with raWOT, you can create webserver you want with only one restriction: no https.
All webservers built for others libraries "arduino" can be ported on aWOT
 
Upvote 0

BertI

Member
Licensed User
Thanks candide, downloaded the library and the littleFs one as well and got the basic example running just fine.

Tested with iPhone Safari and it took roughly 8-10s to bring up the login page. This is similar to the time taken when using a basic Arduino server example as described above in #5. Probably this is not surprising as the server is implemented within the aWOT library rather than using B4R Server socket and astreams constructs. Tested with Firefox on a Windows PC (also connected to router via WiFi not ethernet). In this case the login page came up immediately.

So to me it still seems that there is some issue with iOS connecting to this ESP device but not so noticeable when using perhaps 'more native' arduino or C code (if you'll excuse my vague interpretation) as compared to B4R.

BTW the raWOT library looks quite interesting :)
 
Upvote 0

BertI

Member
Licensed User
Tried a B4J version of the B4R code in my first post (B4J code running on a windows PC). Again connection is WiFi to WiFi via the router. In this case the time between the new socket connection and receiving the GET request data is within milliseconds. So would seem to imply something particular about the interaction between the iOS browser and the B4R implementation and/or ESP8266 module (an ESP-12S).
 
Upvote 0

BertI

Member
Licensed User
Some twisted lateral thinking made me try the following 'adjustment' :

B4X:
Private Sub Server_NewConnection (NewSocket As WiFiSocket)
   Log("NEW server CONNECTION **********  at: ", Millis-st)
   Astream.Initialize(NewSocket.Stream, "astream_NewData", "astream_Error")
   Astream.MaxBufferSize=1000
    If NewSocket.Stream.BytesAvailable=0 Then server.Socket.Close
End Sub

This seems to work but why exactly I'm not sure. This also means I don't know what detrimental effects this could have under some circumstance. Seems I have also rediscovered how to post code.. :)
 
Last edited:
Upvote 0
Top