Open
Description
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;
};
};