Skip to content

Multiple polls for 1 websocket client when using firefox as client #58

Open
@chubby1968

Description

@chubby1968

Describe the bug
ESP32 is configured as server that accepts multiple clients. When connecting from firefox browser using server.poll(), two clients are registered (in most cases).

When this happens, no more code is executed. (It appears to be trapped in handshake part of server.accept() ).

To Reproduce
Using below code, connect to the esp32 board from firefox browser.

  • Library version 0.4.14
  • Board: ESP32-CAM
  • Firefox 71.0 (64-bit)

Expected behavior
Only 1 client is added to the list for each new connection (which is what happens in chrome).

Code

#include <WiFi.h>
#include <ArduinoWebsockets.h>
using namespace websockets;

const char *ssid = "xxxx";
const char *password = "xxxx";
const int maxClients = 4; // Accept up to 4 connections

WebsocketsServer server;
WebsocketsClient clients[maxClients];
int nClients = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial)
    ;

  // WIFI SETUP
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected, IP: ");
  Serial.println(WiFi.localIP());

  // WEBSOCKET: Open websocket on port 80
  server.listen(80);
  Serial.print("Is server live? ");
  Serial.println(server.available());
}

void loop()
{
  if (server.available())
  {
    // if there is a client that wants to connect
    if (server.poll() && nClients < maxClients)
    {
      //accept the connection and register callback
      Serial.print("Accepting a new client! Number of clients accepted: ");
      Serial.println(nClients + 1);
      WebsocketsClient client = server.accept();
      client.onMessage(onMessage);

      // store it for later use
      clients[nClients] = client;
      nClients++;
      delay(10);
    }

    // check for updates in all clients
    pollAllClients();

    delay(10);
  }
}

// this method goes thrugh every client and polls for new messages and events
void pollAllClients()
{
  for (int i = 0; i < nClients; i++)
  {
    clients[i].poll();
  }
}

// this callback is common for all clients, the client that sent that
// message is the one that gets the echo response
void onMessage(WebsocketsClient &client, WebsocketsMessage message)
{
  Serial.print("Got Message: ");
  Serial.print(message.data());
  Serial.println(", Sending Echo.");
  client.send("Echo: " + message.data());
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <link rel="stylesheet" href="../css/style.css" />
        <script src="../js/websocket.js" defer></script>
        <title>Websocket demo</title>
    </head>
    <body>
        <table>
            <thead>
                <th>Status</th>
                <th>Messages received</th>
            </thead>
            <tbody>
                <td id="status">Not connected</td>
                <td id="messages"></td>
            </tbody>
        </table>
        <form>
            <input type="button" id="msg_button" value="Send a msg" />
            <input type="text" placeholder="IP of server" name="IP" id="IP" value="" />
            <input type="button" id="IP_button" value="Configure IP" />
        </form>
    </body>
</html>
let messages = document.querySelector("#messages");
let status = document.querySelector("#status");
let ws;

document.querySelector("#IP_button").onclick = () => {
    
    if(typeof ws !== 'undefined'){
        ws.close();
    }
    ws = new WebSocket("ws://" + document.querySelector("#IP").value);
    status.innerHTML = "Websocket " + ws.readyState;

    ws.onopen = () => {
        status.innerHTML = "Websocket open";
        let i = 0;

        document.querySelector("#msg_button").onclick = () => {
            console.log("click");
            ws.send(i++);
        };

        ws.onmessage = event => {
            console.log(event);
            let txt = messages.innerHTML;
            messages.innerHTML = txt + "<br>" + event.data;
        };
    };

    ws.onclose = () => {
        status.innerHTML = "Websocket closed";
    };

    ws.onerror = event => {
        console.log(event);
        status.innerHTML = "Cannot connect to " + event.target.url;
    };
};

Metadata

Metadata

Assignees

Labels

possible-bugSomething isn't working, and I think it is a bug

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions