Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

How to use websocket on Mongoose OS

BerleseBerlese Brazil
edited May 17 in Mongoose OS

I'm trying to use websocket on mongoose OS, but I don't have found a good example to help me.

I want to do some thing like the wifi-setup-web (with uses http-server, and I need to create a websocket server).
I already found this on Cesanta/Mongoose, WebSocket , and this other here websocket_chat.
But I don't found nothing like the example for HTTP.

But if someone could help me on this matter, will be very helpful =]
I just need a start.

Comments

  • BerleseBerlese Brazil

    To be more specific.

    Could be just a code example, using websocket, to a device on the same wifi network do the follow commands:
    ws://192.168.0.100/rpc/Config.Set or ws://192.168.0.100/rpc/Config.Get

    Where the IP "192.168.0.100" is the ESP32 as a websocket server.

  • SergeySergey Dublin, Ireland

    create a websocket connection
    send a ws frame according to https://mongoose-os.com/docs/book/rpc.html#mg-rpc-frame-format

    Thanked by 1Berlese
  • BerleseBerlese Brazil

    Hello guys! And Thanks @nliviu and @Sergey.
    After a while, reading, understanding and coding... I finally got something.

    At this moment I already have a example, doing what I wanted to do, as follow:

  • BerleseBerlese Brazil

    Is very simple, just two RPC commands, one to Get a global variable (num) and other to Set.

    main.c:

    //---------------------------------------------------------------------------
    // My Includes:
    #include "mgos.h"
    #include "mgos_rpc.h"
    
    #include "common/mg_str.h"
    #include "mgos_config_util.h"
    #include "mgos_hal.h"
    #include "mgos_sys_config.h"
    #include "mgos_utils.h"
    
    //---------------------------------------------------------------------------
    //Global variables:
    int num = 555;
    
    //---------------------------------------------------------------------------
    // Handler for Num.Set
    static void Num_rpc_set_handler(struct mg_rpc_request_info *ri, void *cb_arg,
                                        struct mg_rpc_frame_info *fi,
                                        struct mg_str args) {
    
      if (json_scanf(args.p, args.len, ri->args_fmt, &num) == 1) {
        LOG(LL_INFO, ("OK: %d", num));
      }
      else {
        LOG(LL_INFO, ("ERROR"));
      }
    
      mg_rpc_send_responsef(ri, NULL);
      ri = NULL;
    
      (void) cb_arg;
      (void) fi;
    }
    
    //---------------------------------------------------------------------------
    // Handler for Num.Get
    static void Num_rpc_get_handler(struct mg_rpc_request_info *ri, void *cb_arg,
                                        struct mg_rpc_frame_info *fi,
                                        struct mg_str args) {
    
      struct mbuf send_mbuf;
      struct json_out jsout = JSON_OUT_MBUF(&send_mbuf);
      mbuf_init(&send_mbuf, 0);
    
      int var = 0;
      json_scanf(args.p, args.len, ri->args_fmt, &var);
    
      json_printf(&jsout, "{num: %d}", num);
      LOG(LL_INFO, ("OK, var=%d", var));
    
      mbuf_append(&send_mbuf, "", 1);
      mg_rpc_send_responsef(ri, "%s", send_mbuf.buf);
      ri = NULL;
    
      mbuf_free(&send_mbuf);
    
      (void) cb_arg;
      (void) args;
      (void) fi;
    }
    
    //---------------------------------------------------------------------------
    // Initialization
    enum mgos_app_init_result mgos_app_init(void) {
      struct mg_rpc *c = mgos_rpc_get_global();
      mg_rpc_add_handler(c, "Num.Set", "{num: %d}", Num_rpc_set_handler, NULL);
      mg_rpc_add_handler(c, "Num.Get", "{var: %d}", Num_rpc_get_handler, NULL);
    
      return MGOS_APP_INIT_SUCCESS;
    }
    
    //---------------------------------------------------------------------------
    
    

    mos.yml modifications:

    # List of libraries used by this app, in order of Initialization
    libs:
      - origin: https://github.com/mongoose-os-libs/ca-bundle
      - origin: https://github.com/mongoose-os-libs/rpc-service-config
      - origin: https://github.com/mongoose-os-libs/rpc-service-fs
      - origin: https://github.com/mongoose-os-libs/rpc-uart
      - origin: https://github.com/mongoose-os-libs/wifi
      - origin: https://github.com/mongoose-os-libs/http-server
      - origin: https://github.com/mongoose-os-libs/dns-sd
    
    config_schema:
      # dns:
      - ["dns_sd.enable", true]
      - ["dns_sd.host_name", "websocket"]
      # wifi:
      - ["wifi.ap.enable", false]
      - ["wifi.sta.enable", true]
      - ["wifi.sta.ssid", "your_wifi_ssid"]
      - ["wifi.sta.pass", "your_wifi_password"]
    
  • BerleseBerlese Brazil
    edited May 23

    And here is a very simple html, to make a websocket communication test:

    <!DOCTYPE html>
    <html lang="pt-br"></html>
    
    <html>
      <head>
        <meta charset="utf-8"/>
    
        <title>Web test</title>
    
        <script type = "text/javascript">
          function WebSocketTest() {
            var wsUri = 'ws://websocket.local/rpc';
    
            if ("WebSocket" in window) {
              console.log("WebSocket is supported by your Browser! IP:" + wsUri);
    
              // Let us open a web socket
              let ws = new WebSocket(wsUri);
    
              ws.onopen = function() {
    
                  // Web Socket is connected, send data using send()
                  ws.send(JSON.stringify({
                    method: "Num.Set",
                    args: {
                      num: 9999
                    }
                  }));
              };
    
              ws.onmessage = function (evt) { 
                  var received_msg = evt.data;
                  console.log(received_msg);
              };
    
              ws.onclose = function() { 
    
                  // websocket is closed.
                  console.log("Connection is closed..."); 
              };
            } else {
    
              // The browser doesn't support WebSocket
              alert("WebSocket NOT supported by your Browser!");
            }
          }
       </script>
      </head>
    
      <body>
        <div id = "sse">
            <a href = "javascript:WebSocketTest()">Run WebSocket</a>
        </div>
      </body>
    
    </html>
    

    I just opened this html on my pc browser and tested.
    =]

  • BerleseBerlese Brazil

    So, why am I posting all this?

    First of all, to share the code (may this be useful for others).

    But the main motivation is that now I want to do something else.
    At this point, the ESP32 works as a "websocket server" that could receive RPC commands from another device in the same network (as the example that I showed), giving back information to the device (in the example, my pc).
    But if I want that the server (the ESP32) sends data to a specific device (for example, my PC, on IP:192.168.0.107) without the RPC call from the device (I want to use the RPC Set and Get, but I need something else too). I want send a data from the ESP32 via websocket in a "asynchronous mode".
    Because I don't want the device continuously requesting data to the server (pulling mode).

    So... what can I do?
    And, congratulations for your great work on mongoose OS. =]

  • BerleseBerlese Brazil

    Nobody can give me a little help?

    At least, say if is possible... Thanks

  • I think that you don't need an rpc on ESP but you need a listener on your pc , set a timer in ESP and periodically post data using that timer
Sign In or Register to comment.