cesanta / mongoose-os

Mongoose OS - an IoT Firmware Development Framework. Supported microcontrollers: ESP32, ESP8266, CC3220, CC3200, STM32F4, STM32L4, STM32F7. Amazon AWS IoT, Microsoft Azure, Google IoT Core integrated. Code in C or JavaScript.
https://mongoose-os.com
Other
2.51k stars 429 forks source link

ESP32 MQTT Broker Over WS #609

Closed JonRobo closed 1 year ago

JonRobo commented 1 year ago

Hello I have successfully gotten a very capable MQTT broker over the standard mqtt/tcp transport, but am facing a strong need for this broker to be using the websocket transport. The code largely resembles the example here.

My issue is that when my ESP32 MQTT client attempts to connect to my broker 'ws://IP:80 I get the following errors

E (141875) mqtt_client: Error transport connect I (141885) MQTTWS_EXAMPLE: MQTT_EVENT_ERROR I (141885) MQTTWS_EXAMPLE: Last errno string (Success) I (141895) MQTTWS_EXAMPLE: MQTT_EVENT_DISCONNECTED I (156895) MQTTWS_EXAMPLE: Other event id:7 E (166915) transport_ws: Error read response for Upgrade header GET /mqtt HTTP/1.1 Connection: Upgrade Host: 192.168.4.1:80 User-Agent: ESP32 Websocket Client Upgrade: websocket Sec-WebSocket-Version: 13 Sec-WebSocket-Key: YgzMX444yESKVbCdnrrtyQ== Sec-WebSocket-Protocol: mqtt

I use a MQTT client on the broker as well to keep track of a list of clients and notify those interested.

This part of the code within the broker works

void mqtt_list_handler(void pvParameters) { char task_parameter = (char *)pvParameters; char url[64]; strcpy(url, task_parameter); ESP_LOGI(pcTaskGetName(NULL), "started on %s", url);

struct mg_mgr _mgr;
    struct mg_mqtt_opts opts;                                                 // MQTT connection options
mg_mgr_init(&_mgr);                                              // Initialise event manager
memset(&opts, 0, sizeof(opts));                 // Set MQTT options
opts.keepalive = 60;
opts.user = mg_str(BRIDGE_USER);
opts.pass = mg_str(BRIDGE_PW);
opts.version = 0x04;
opts.client_id = mg_str(pcTaskGetName(NULL));   // Set Client ID

struct mg_connection *mgc;
mgc = mg_mqtt_connect(&_mgr, url, &opts, fn, &url); // Create client connection

while(!CLIENT_CONNECTED) // if We're not connected, then get connected
{
        s_wifi_event_group = xEventGroupCreate();
        EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, MQTT_CONNECTED_BIT, pdFALSE, pdTRUE, 0);
        vTaskDelay(500); 
        ESP_LOGI(pcTaskGetName(NULL), "Checking for List Client Connection");
        mg_mgr_poll(&_mgr, 0);
}
ESP_LOGI(pcTaskGetName(NULL), "url=[%s], client id = %.*s", url,(int)opts.client_id.len, opts.client_id.ptr);
struct mg_str get_list_topic = mg_str(robo_get_list_topic);
mg_mqtt_sub(mgc, get_list_topic, SUB_QOS);
ESP_LOGI(pcTaskGetName(NULL), "SUBSCRIBED to %.*s", (int)get_list_topic.len, get_list_topic.ptr);

/* Processing events */
while (true) 
{
    vTaskDelay(100);      
    mg_mgr_poll(&_mgr, 0);
}

// Never reach here
ESP_LOGI(pcTaskGetName(NULL), "Exited Robo Lists Loop\n");
mg_mgr_free(&_mgr);                             // Finished, cleanup

}

Hoping for any sort of help to get my other devices to connect successfully over a websocket connection as well. Thanks in advance

DrBomb commented 1 year ago

I see tasks, groups and other things. Are you using MongooseOS the framework for IoT? Or mongoose the network library?

scaprile commented 1 year ago

Please use the proper repository and fill the issue template when you do it. Make sure you also have read the docs before that (see below) and checked the tons of examples and tutorials explaining how to properly do what you want to do.

NOTE: Since Mongoose's core is not protected against concurrent accesses, make sure that all mg_* API functions are called from the same thread or RTOS task.

If you absolutely need multi-threading, take the time to go through the user guide (linked above) and tutorials, there is one that shows you how to do multi-threading.

JonRobo commented 1 year ago

Hello,

I am using ESP-IDF V5.0 and Mongoose OS v7.9. That's very encouraging to hear that an MQTT Broker that can handle Websocket connections is possible, however I have not found any tutorials about this, only for an MQTT WS client.

I will make another issue in the linked repository and look to follow the template.

I have a few more ideas on how I may be able to solve this such as using a mongoose OS MQTT client connection on my other boards instead of the ESP IDF c;ient, and updating to Mongoose OS V7.10.