-
Notifications
You must be signed in to change notification settings - Fork 424
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
how to implement an async client? #738
Comments
By
OK.
No need to do this using TCP as data is guarenteed to arrive unless the TCP layer session fails.
libcoap supports events through the event handler that indicates to the application that there are issues with the connection and that there has been a disconnection of some sort.
See previous comments.
Multi-threading support is not available - a future TODO with no timescales.
OK
Yes - see outstanding PR #701 for how to do this. You need to call coap_io_process() so that the responses hare handled.
No. Use the same session when talking to the same host. See #701.
As mentioned previously, you need to set up the event handler and monitor the disconnect type events - see man page coap_handler(3). Then create another client session to continue with the traffic (see coap_endpoint_client(3)). |
As confirmable I currently understand a message that has a deliver confirmation response, while a non-confirmable is the one that doesn't have it. I understand the differences between TCP and UDP, but what is new to me is why confirmable and non-confirmable PDU types are not applicable for TCP. Why? Am I wrong? By 'without blocking' I mean, call coap_send() and don't block. But being able to check if it was sent or not in the future.
If I call coap_send() with a confirmable message, is it 100% that it will be delivered? Like a QoS 1/2 in MQTT?
Got it.
Got it.
Ok.
I tried the modified coap-client with -G option to calling coap_io_process(). I think it isn't the most efficient thing to do because I would have to split my data events into chuncks... like, if I have 1000 events to send, I would split into 10 batches of 100 events each... coap_send() 100 times, coap_io_process(), coap_send() more 100 times... until the end. Is it the concept?
Great.
Ok.
I think a good advancement for libcoap or coap community in general is work to make it more user friendly. If you compare libmosquitto basic examples with libcoap, libcoap is more more complex and I felt more examples are missing. Maybe I could help to improve it, while I'm learning about the protocol and getting more comfortable with the code base ;) |
Thanks for using libcoap. The library initially has intentionally been designed to give application developers access to the lower layer CoAP protocol. If you want to control certain behavior, it is therefore crucial to have a working knowledge of CoAP and the underlying transport protocols. For more basic usage, several example applications such as the coap-client.c or liboap-minimal exist. |
As per https://datatracker.ietf.org/doc/html/rfc8323#section-3.1 (CoAP over TCP)
So CON / NON / ACK / RST Types are not used because TCP is a reliable protocol.
If the PDU cannot immediately be sent, it will get queued for sending (subject to RAM limitations). Note that when using CON, only 1 CON can be inflight as controlled by NSTART (default of 1) - see https://datatracker.ietf.org/doc/html/rfc7252#section-4.7 . If there is a queing or other failure, then COAP_INVALID_MID is returned.
No. Depending on the Congestion Control parameters it will get resent multiple times until a failure event is generated.
You can do this if you want - just remember with UDP and CON you will be queing up the 99 events (coap_send() will send the first one) and each call to coap_io_process() will be checking that the previous CON has been acknowleged and only then (as NSTART has dropped below 1) will the the next queued CON be sent by coap_io_process(). With TCP, you are subject to the TCP stack limitations. |
Thank you so much for such a rich and detailed explanation! About the PDU and queueing:
Why in this code snippet I'm loosing the last (or the tail messages) and getting a |
I think the cuplrit here is Removing |
Is there any way to check how many requests has been enqueued? To exit as soon as there is no more responses, maybe I will have to keep track of the sent requests and check how many responses went back. |
No. You need to keep a tally of what was sent and what has been responded to. (Each request should have an unique token and the response's token is used to match the appropriate request). |
Wait for wait_ms (in the case any response is lost), try every 250ms (ajustable) and exit as soon as req_rep is zero (all sent requests got a response).
It seems to work! |
Excellent! |
Sorry about asking so many things, still learning. Why do you think CoAP has no "enterprise" servers like on MQTT (emq, mosquito, etc)? I think a huge boost for CoAP would be to look at it more as a final platform, instead of as a specification and base implementation only. What do you think about it? I think the request/response model fits very well when you have to ensure that data has been transmitted from client to server, while only deleting data from client if it's persisted on server (like on Kafka). This is a pattern where having a broker + sub publishing to Kafka is unreliable, if the sub goes down you will not persist messages anymore. CoAP fits very well for end-to-end persistence! |
I am aware of (enterprise level) bespoke applications that are using CoAP as a transport layer which is provided for by libcoap. These bespoke applications are not a generic enterprise server with lots of configuration options defining the required functionality that I think you are looking for. That said, there is no reason as to why someone could not do this as a project. As obgm mentioned previously the roots of libcoap came from different intentions, but the product has evolved making the licoap layer more robust as well as internally handling some specific CoAP functionality should the application layer not want to handle things - e.g. RFC7959 block handling. |
In the first comment it was said, that CoAP over TCP is mandatory. If that wouldn't be the case, at least from the performance, scalability and availability perspective, Eclipse/Californium does the job for many larger server-sides. The upcoming release 3.0 provides in combination with DTLS-CID:
If once up on a day the providers in Brazil support UDP, you may try it out. |
First of all, thank you so much for CoAP protocol and implementation. I didn't know anything about CoAP since 3 days ago, so I'm still reading the code base and experimenting with.
I'm trying to implement an async client in C and use the go-coap as the base for the server side. The client basic requirements are:
Is it possible to have two threads, one to send and the other to receive the responses at the client side?
I tried to call coap_send() consecutively, but it wen't wrong. Can I use the same context and session and call coap_send() infinite times? Do I need to create a conext/session per coap_send() call?
How can I monitor the UDP/TCP socket states to detect disconnections and be able to force a reconnection? Does it works like ZeroMQ or NNG where you don't have to care about reconnections directly (yes, sometimes you must force-reconnect, but reconnections are usually automatic)?
As soon my implementation advances and works, I plan to publish it as an example for the great libcoap!
Thank you so much for supporting!
The text was updated successfully, but these errors were encountered: