Open pvint opened 3 years ago
Hello
I'm quite a beginner, but I don't mind that I can't use several devices. I stumbled upon the limitation of the TCP send buffer in the LwIP. This can be adjusted. By default it is set to 5744 bytes. Twice as much buffer is required as bytes are sent. That would fit with the 2828 bytes.
It is possible to increase the buffer to 28,000 bytes. Unfortunately, I do not know how to adjust the settings.
CONFIG_LWIP_TCP_SND_BUF_DEFAULT
tcp_sndbuf (_pcb)
I have found that the device info in response to the initial request for listing ALL devices doesn't have to be so detailed. It looks to be sufficient just to have the device reference number, the name and the unique ID for each device. This could make this response shorter when you have multiple devices.
Me too
I created this shortened version:
// Add in a short version for the ALL PROGMEM const char FAUXMO_DEVICE_JSON_TEMPLATE_SHORT[] = "{" "\"type\": \"Extended color light\"," "\"name\": \"%s\"," "\"uniqueid\": \"%s\""
"}"; and called that whenever the request for ALL is made. It works perfectly - I can now add all my 15 devices, and probably more.
@all: Nice work!
My time is a bit short lately, but I will definitely be looking into the send buffer changes as mentioned by @Dani-Hg
For now, I'd like to test and implement the changes mentioned by @kzkaram & @b1gmans
If you have the time and inclination, could you submit a PR? (Just to save me a bit of time ;) )
Just to note... no need to tweak CONFIG_LWIP_TCP_SND_BUF_DEFAULT or any lwip settings. The general flow should just accept that client->add() may fail and it should buffer the data until the client->space() != 0 when network is done sending.
i.e. implement what generic wificlient does, and stall until the network is done with the data to send another chunk. Maybe hook into onAck, which will be called when the remote accepts the data. Or, onPoll, which is periodically called (although a bit slow) while the connection is active
Good point - I'll try that. We use client-write()
currently, and I think it could be changed to use client->add()
then client->send()
For my own reference, here's the relevant excerpt from AsyncTCP.h:
size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending
bool send();//send all data added with the method above
//write equals add()+send()
size_t write(const char* data);
size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true
Pretty much, yes. ref. pretty recent update to the async-mqtt-client https://github.com/marvinroger/async-mqtt-client/blob/2991968a97193aaa6402d146490b93ea671c7e02/src/AsyncMqttClient.cpp#L399-L465 data blobs are placed into queue, and _handleQueue() is called on every opportunity - onAck, onConnected, onPoll, etc.
which closely follows what espasyncwebserver does with the websocket implementation. or what espurna does with buffered telnet server, and terminal output overall
Hey all, I see this thread had activity about a year ago with report that device count could be extended by slimming down device information in the responses, but it seems like this will still create a relatively low limit on number or maximum devices. When I say low limit, I'm considering the application I'm looking for in that I'm working to expose about 140 relays (chained 16 channel relay boards) to Alexa.
Unfortunately my knowledge of APIs is pretty limited, but my mind immediately asks the question, "Can you tell the requester to expect multiple responses?" Basically, when Alexa initiates a discovery, can we tell it to expect multiple responses back and then effectively break up the devices into distributed bulk payloads of say 10 devices each?
Mostly an ESP8266 issue, but it occurs on ESP32 at higher numbers of devices.
When doing device discovery, when the Alexa device sends
GET /api/2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr/lights HTTP/1.1
and there are too many devices the response gets truncated.When (ESP)AsyncTCP doesn't have "room", the remainder gets truncated in AsyncClient::add.
Need to figure out how to split up the response (or worst case, at least warn the user about what has happened)
Ref: #150
Some debugging info: