Closed nkolban closed 3 years ago
mg_broadcast()
is using socketpair. A thread that sends a brodcasts writes to the one end of a socketpair, that wakes up and IO thread that reads from another end, and receives a message.
A socketpair is created using loopback, 127.0.0.1.
I have a suspicion that on ESP32, just like on ESP8266, the loopback is not enabled in LWIP. @rojer @alashkin do you have any more state on that?
When I tried to port Mongoose networking myself back in 2016 I found that 127.0.0.1 wasn't working ... see the following issue ... https://github.com/espressif/esp-idf/issues/114
A poster to that thread claims that 0.0.0.0 works as does the local IP address.
In the ESP-IDF world, there are also other synchronization mechanisms including queues and semaphores at the FreeRTOS level.
If using a 127.0.0.1 socket pair isn't going to work easily on the ESP32, might we consider some ESP32/RTOS alternative mechanism defined at build time?
Was this issue ever resolved? Is "mg_broadcast" a supported function in ESP32 Mongoose networking?
What I have is a situation where, when I receive an incoming MG_EV_WEBSOCKET_FRAME event, I need to send back a response. I am under the belief that I can't invoke mg_send_websocket_frame() in the event handler that receives the MG_EV_WEBSOCKET_FRAME and hence am looking for a good design to achieve my goal.
Hi Neil. Inspired by the book you wrote on the esp32, i've written a small project where i have worked my way around the above problem by using FreeRTOS queues. see: https://github.com/klapligehesten/esp32_mg_web
I can confirm that mg_broadcast works on ESP-IDF commit e7dc749e2f953a976325964b5ac49b53c8bafc42
@cpq @Eloquence4 @nkolban Could you please share with me how you got mg_broadcast working? I believe the API is pretty straightforward, however I can't get mg_broadcast to work.
I am running a websocket server just fine and I am able to receive data without any issues. To test mg_broadcast (and make sure no other tasks were interfering), I simply created a second task in FreeRTOS which runs every 10 seconds (using vTaskDelay). For testing purposes I created a local (static) struct mg_mgr mgr; in the .c file, so that both tasks can access the Mongoose manager.
I noticed that the task is actually locking up. By adding several debug (ESP_LOGD / LOGI) statements, I was able to identify that mg_broadcast never returns. Within function mg_broadcast (mongoose.c), every function call returns up until the last one: dummy = MG_RECV_FUNC(mgr->ctl[0], (char *) &len, 1, 0);
The callback function that gets passed into mg_broadcast is even called, so we know that mg_mgr_poll
wakes up and the callback function is called from within the mg_mgr_poll thread/task. However, MG_RECV_FUNC
never returns. I did not make any changes to Mongoose (besides adding #define MG_ENABLE_BROADCAST 1
to enable mg_broadcast functionality), so MG_RECV_FUNC
is simply mapped to recv
(default).
I validated that LwIP loopback support is enabled, based on the issue @nkolban raised here. Since I did not make any changes to the default project config, loopback support is enabled.
It almost looks like it has something to do with the socketpair struct mg_mgr::ctl
that's used to enable inter-process communication via mg_broadcast. But I can't figure out what's causing the function to block and thus lockup the entire task.
I am running Mongoose 6.11 and the latest version of ESP-IDF (I just pulled it from GitHub). I also tested with ESP-IDF v3.0-rc1, older versions of Mongoose, older versions of ESP-IDF and a combination of those.
@nkolban on a side note, I placed Mongoose in its own component folder. I tried defining MG_ENABLE_BROADCAST in the component makefile, using CFLAGS += -DMG_ENABLE_BROADCAST=1
. Unfortunately that did not have any effect. When I place this into the project Makefile, it does work. I saw you ran into something similar, did you find a solution?
Thanks!
This is the example code i used to test mg_broadcast with: https://pastebin.com/tgV8ZcgL I can't really test if the task deletes itself right now, i will comment back when i can.
@Eloquence4 thanks for your reply. I am currently working on a small example project that will demonstrate the issue. Perhaps you can spot an issue in the code. I will post asap.
@cpq @Eloquence4 I just created a test project that demonstrates the issue, you can find it here. I assume the mg_broadcast callback is called 1 + N times, where N is the number of user sockets. I assume it's called for the loopback socket as well, hence the +1. Can you confirm?
I can also create a new issue, as this issue post dates back to 7 Feb 2017 and my issue is perhaps due to a newer version of Mongoose and/or ESP-IDF.
Created a new issue here for clarity's sake.
Update 19-02-2018: The issue has been resolved.
Not building for me linker error on esp32.
undefined reference to `mg_broadcast'
I have defined
extern "C" {
}
Any idea?
Closing this.
The latest code has diverted from the mg_broadcast
concept. Instead, it provides a socketpair API for the inter-task comms. See an example at https://github.com/cesanta/mongoose/tree/master/examples/multi-threaded
Howdy folks, ... in a project I need to publish on a WebSocket when an event in my ESP32 occurs. I understand that I am not allowed to simply call
mg_send_websocket_frame()
in a separate task/thread and that makes sense. I am also of the understanding that the correct way to achieve my goal is to invokemg_broadcast
in my originating thread which will cause an event to be generated in my event handling loop where I can then perform the web socket send.With this background ... I seem to find that
mg_broadcast
is disabled by default. I then changed my build process to defineMG_ENABLE_BROADCAST
and themg_broadcast()
function became present. However, I have not been able to get it to work. When I invokemg_broadcast
, no event is generated.Is the
mg_broadcast
functionality working in the ESP32 port of the Mongoose networking library?