Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for receiving message only if data is ready #39

Open
trepidacious opened this issue Jul 2, 2024 · 0 comments · May be fixed by #40
Open

Support for receiving message only if data is ready #39

trepidacious opened this issue Jul 2, 2024 · 0 comments · May be fixed by #40

Comments

@trepidacious
Copy link

trepidacious commented Jul 2, 2024

Currently it seems to be hard to use one socket to both send and receive messages. I'm not sure whether it's actually possible to read messages that might have a gap longer than the connection timeout, since receive_message will block until it receives a message, which means you can't send a ping to keep the connection alive, leading to the issue in #36. #38 suggests that this can't be done with a select as recommended in #36, since it seems that data could be lost if the receive is cancelled after reading partial data.

I think I've got at least a partial solution to this - at least with some io implementations we will have ReadReady available as well as Read + Write, and this allows checking whether there is at least one byte of data available to be read immediately. This means we can implement a new receive_message_if_ready method - this will return immediately if there is no data available to read immediately, otherwise it will pass through to the existing receive_message method.

Technically this doesn't seem like a full fix - you could still have a case where a partial message comes through and then the rest is delayed, however I don't think this is really a problem. If you have a partial message then no more data received for more than a few seconds, it probably indicates that the connection or server is down and there's not much point in returning early from receive to e.g. send a ping, and I'd guess eventually the socket will either recover or close. It does fix the presumably much more common issue where everything is fine on the server, client and connection - there's just a long gap between incoming messages, but each message comes through relatively quickly after the first byte.

I'll submit a PR for the implementation, it doesn't really change anything much except adding the "if_ready" version of receive and poll methods, in the case where you have ReadReady available.

Side note - there is currently an issue with embassy-net where read_ready() is not implemented correctly for TcpSocket, this is fixed in main but not in the current 0.4.0 release. I've tested this approach on an esp32c3 with the fixed embassy-net and it seems to work fine for a loop with receive_message_if_ready() and send_ping(), staying connected overnight even if no messages are being received.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant