Git Product home page Git Product logo

arduinowebsockets's Introduction

arduino-library-badge Build Status

Arduino Websockets

A library for writing modern websockets applications with Arduino (see prerequisites for supported platforms). This project is based on my project TinyWebsockets.

The library provides simple and easy interface for websockets work (Client and Server). See the basic-usage guide and the examples.

Please check out the TinyWebsockets Wiki for many more details!

Getting Started

This section should help you get started with the library. If you have any questions feel free to open an issue.

Prerequisites

Currently (version 0.5.*) the library only works with ESP8266, ESP32 and Teensy 4.1.

Installing

You can install the library from the Arduino IDE or using a release ZIP file from the Github release page. Detailed instructions can be found here.

Basic Usage

Client

Creating a client and connecting to a server:

WebsocketsClient client;
client.connect("ws://your-server-ip:port/uri");

Sending a message:

client.send("Hello Server!");

Waiting for messages:

client.onMessage([](WebsocketsMessage msg){
    Serial.println("Got Message: " + msg.data());
});

In order to keep receiving messages, you should:

void loop() {
    client.poll();
}

Server

Creating a server and listening for connections:

WebsocketsServer server;
server.listen(8080);

Accepting connections:

WebsocketsClient client = server.accept();
// handle client as described before :)

Full Examples

Client

#include <ArduinoWebsockets.h>
#include <ESP8266WiFi.h>

const char* ssid = "ssid"; //Enter SSID
const char* password = "password"; //Enter Password
const char* websockets_server = "www.myserver.com:8080"; //server adress and port

using namespace websockets;

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("Connnection Opened");
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("Connnection Closed");
    } else if(event == WebsocketsEvent::GotPing) {
        Serial.println("Got a Ping!");
    } else if(event == WebsocketsEvent::GotPong) {
        Serial.println("Got a Pong!");
    }
}

WebsocketsClient client;
void setup() {
    Serial.begin(115200);
    // Connect to wifi
    WiFi.begin(ssid, password);

    // Wait some time to connect to wifi
    for(int i = 0; i < 10 && WiFi.status() != WL_CONNECTED; i++) {
        Serial.print(".");
        delay(1000);
    }

    // Setup Callbacks
    client.onMessage(onMessageCallback);
    client.onEvent(onEventsCallback);
    
    // Connect to server
    client.connect(websockets_server);

    // Send a message
    client.send("Hi Server!");
    // Send a ping
    client.ping();
}

void loop() {
    client.poll();
}

Note: for ESP32 you only need to change to code that connects to WiFi (replace #include <ESP8266WiFi.h> with #include <WiFi.h>), everything else stays the same.

Server

#include <ArduinoWebsockets.h>
#include <ESP8266WiFi.h>

const char* ssid = "ssid"; //Enter SSID
const char* password = "password"; //Enter Password

using namespace websockets;

WebsocketsServer server;
void setup() {
  Serial.begin(115200);
  // Connect to wifi
  WiFi.begin(ssid, password);

  // Wait some time to connect to wifi
  for(int i = 0; i < 15 && WiFi.status() != WL_CONNECTED; i++) {
      Serial.print(".");
      delay(1000);
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());   //You can get IP address assigned to ESP

  server.listen(80);
  Serial.print("Is server live? ");
  Serial.println(server.available());
}

void loop() {
  auto client = server.accept();
  if(client.available()) {
    auto msg = client.readBlocking();

    // log
    Serial.print("Got Message: ");
    Serial.println(msg.data());

    // return echo
    client.send("Echo: " + msg.data());

    // close the connection
    client.close();
  }
  
  delay(1000);
}

Note: for ESP32 you only need to change to code that connects to WiFi (replace #include <ESP8266WiFi.h> with #include <WiFi.h>), everything else stays the same.

Binary Data

For binary data it is recommended to use msg.rawData() which returns a std::string, or msg.c_str() which returns a const char*. The reason is that msg.data() returns an Arduino String, which is great for Serial printing and very basic memory handling but bad for most binary usages.

See issue #32 for further information.

SSL and WSS Support

No matter what board you are using, in order to use WSS (websockets over SSL) you need to use

client.connect("wss://your-secured-server-ip:port/uri");

The next sections describe board-specific code for using WSS with the library.

ESP8266

With the esp8266 there are multiple ways for using WSS. By default, ArduinoWebsockets does not validate the certificate chain. This can be set explicitly using:

client.setInsecure();

You can also use a SSL Fingerprint to validate the SSL connection, for example:

const char ssl_fingerprint[] PROGMEM = "D5 07 4D 79 B2 D2 53 D7 74 E6 1B 46 C5 86 4E FE AD 00 F1 98";

client.setFingerprint(ssl_fingerprint);

or you could use the setKnownKey() method to specify the public key of a certificate in order to validate the server you are connecting to.

PublicKey *publicKey = new PublicKey(public_key);
client.setKnownKey(publicKey);

or you can specify the Certificate Authority (CA) using setTrustAnchors method, as follows:

X509List *serverTrustedCA = new X509List(ca_cert);
client.setTrustAnchors(serverTrustedCA);

For client-side certificate validation, you can use RSA or EC certificates, using the method setClientRSACert or setClientECCert .

ESP32

With the esp32 you could either provide the full certificate, or provide no certificate. An example for setting CA Certificate:

const char ssl_ca_cert[] PROGMEM = \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
    "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
    "DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
    "SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
    "GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
    "AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
    "q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
    "SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
    "Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
    "a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
    "/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
    "AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
    "CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
    "bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
    "c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
    "VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
    "ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
    "MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
    "Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
    "AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
    "uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
    "wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
    "X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
    "PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
    "KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
    "-----END CERTIFICATE-----\n";

client.setCACert(ssl_ca_cert);

TEENSY 4.1

Currently WSS is not implemented.

Contributing

Contributions are welcomed! Please open issues if you have troubles while using the library or any queshtions on how to get started. Pull requests are welcomed, please open an issue first.

Contributors

Thanks for everyone who reported a bug, suggested a feature and contributed to the development of this library.

arnoson
⭐️ arnoson

ramdor
⭐️ ramdor

xgarb
⭐️ xgarb

matsujirushi
matsujirushi

bastienvans
bastienvans

johneakin
johneakin

lalten
lalten

adelin-mcbsoft
⭐️ adelin-mcbsoft

Jonty
⭐️ Jonty

Nufflee
Nufflee

mmcArg
mmcArg

JohnInWI
JohnInWI

logdog2709
logdog2709

elC0mpa
elC0mpa

oofnik
⭐️ oofnik

zastrixarundell
⭐️ zastrixarundell

elielmarcos
elielmarcos

Change Log

  • 14/02/2019 (v0.1.1) - Initial commits and support for ESP32 and ESP8266 Websocket Clients.
  • 16/02/2019 (v0.1.2) - Added support for events (Pings, Pongs) and more internal improvements (events handling according to RFC-6455)
  • 20/02/2019 (v0.1.3) - Users now dont have to specify TCP client types (ESP8266/ESP32) they are selected automatically.
  • 21/02/2019 (v0.1.5) - Bug Fixes. Client now exposes a single string connect interface.
  • 24/02/2019 (v0.2.0) - User-facing interface is now done with Arduino's String class. Merged more changes (mainly optimizations) from TinyWebsockets.
  • 25/02/2019 (v0.2.1) - A tiny patch. Fixed missing user-facing strings for client interface.
  • 07/03/2019 (v0.3.0) - A version update. Now supports a websockets server, better support for fragmented messages and streams. bug fixes and more optimized networking implementations.
  • 08/03/2019 (v0.3.1) - Small patch. Merged changes from TinyWebsockets - interface changes to callbacks (partial callbacks without WebsocketsClient& as first parameter).
  • 12/03/2019 (v0.3.2) - Fixed a bug with behaviour of WebsokcetsClient (copy c'tor and assignment operator). Added close codes from TinyWebsockets. Thank you @ramdor
  • 13/03/2019 (v0.3.3) - Fixed a bug in the esp8266 networking impl. Thank you @ramdor
  • 14/03/2019 (v0.3.4) - changed underling tcp impl for esp8266 and esp32 to use setNoDelay(true) instead of sync communication. This makes communication faster and more relaiable than default. Thank you @ramdor for pointing out these methods.
  • 06/04/2019 (v0.3.5) - added very basic support for WSS in esp8266 (no support for fingerprint/ca or any kind of chain validation).
  • 22/04/2019 (v0.4.0) - Added WSS support for both esp8266 and esp32. E328266 can use client.setInsecure() (does not validate certificate chain) or client.setFingerprint(fingerprint) in order to use WSS. With ESP32 there is client.setCACert(certificate) that can be used. (Usage is same as the built in WiFiClientSecure).
  • 18/05/2019 (v0.4.1) - Patch! Addressed an error with some servers. The bugs where first noted in issue #9. Bug was that some servers will drop connections that don't use masking, and TinyWebsockets does not use masking by default. TinyWebsockets changed that and this library merged the changes.
  • 24/05/2019 (v0.4.2) - Patch! Adressed masking issues - server to client messages would get masked but RFC forbbids it. (changes merged from TinyWebsockets)
  • 07/06/2019 (v0.4.3) - Patch! Fixed a bug on some clients (mainly FireFox websokcets impl). Thank you @xgarb (related issue)
  • 09/06/2019 (v0.4.4) - Patch! Fixed an issue with close event callback not called in some cases (sudden disconnect, for example). Thank you @adelin-mcbsoft for pointing out the issue (related issue)
  • 14/06/2019 (v0.4.5) - Patch! Fixed a memory leak and an unnecessary use of heap memory in case of masking messages. This was discoverd thanks to issue #16. Thank you xgarb!
  • 13/07/2019 (v0.4.6) - Very small update. Changed readme to document esp32's secured client behvior (As discussed in issue #18). Also esp32's version of WebsocketsClient now has a setInsecure method. Thank you adelin-mcbsoft!
  • 25/07/2019 (v0.4.7) - Bugfix. Fixed issues with receving large messages (unchecked reads) which was pointed out in in issue #21). Thank you Jonty!
  • 26/07/2019 (v0.4.8) - Feature. Added an addHeader method as suggested in issue #22). Thank you mmcArg!
  • 01/08/2019 (v0.4.9) - Patch - Bugfix. Worked around a bug where connecting to unavailable endpoints would not return false (this is a bug with the WiFiClient library itself). Added some missing keywords. Thank you Nufflee for pointing out the issue!
  • 10/08/2019 (v0.4.10) - Patch - Bugfix. Fixed a bug (and general in-stability) caused from unchecked and unsafe read operations on sockets. Also improved memory usage and management. Thank you Jonty for openning and helping with the issue!
  • 14/09/2019 (v0.4.11) - Bugfixes - masking settings used to not get copied when using assignment between WebsocketClient instances. Also handshake validation is now case insensitive. Thank you logdog2709 for pointing out the issue.
  • 12/10/2019 (v0.4.12) - Patch - Messages are now sent as a single TCP buffer instead of separate messages. Thank you elC0mpa for posting the issue.
  • 19/10/2019 (v0.4.13) - Patch - added yield calls in order to prevent software-watchdog resets on esp8266 (on long messages). Thank you elC0mpa for documenting and helping with the issue.
  • 22/11/2019 (v0.4.14) - Added rawData and c_str as acccessors in WebsocketsMessage so now the raw data can be acccessed which should solve issue #32 and not break any existing sketch.
  • 24/02/20 (v0.4.15) - Added Origin and User-Agent headers to requests sent by the library, this seems to be required by some servers. Thank you imesut for pointing out the issue.
  • 21/04/20 (v0.4.16) - Merged pull request by @oofnik which added 2 way SSL auth for ESP32 and ES8266. Thank you very oofnik for the contribuation.
  • 25/04/20 (v0.4.17) - Merged pull request by Luka Bodroža (@zastrixarundell) which fixed issue #69 - default headers (like Origin, Host) are now customizable via the addHeader method. Thank you zastrixarundell for the contribution.
  • 23/07/20 (v0.4.18) - Merged pull request by Adelin U (@adelin-mcbsoft) which fixed issue #84 - SSL bug-fixing, implemented public-key certificate validation & EC Certificates for client-side. Thank you Adelin!
  • 28/11/20 (v0.5.0) - Support for Teensy 4.1 added by the awesome @arnoson. Supporting plaintext client/server communication and providing new and useful examples. Thank you arnoson!
  • 10/05/21 (v0.5.1) - Fingerprints and Certificates in the examples were updated by @Khoi Hoang . Thank you Khoi!
  • 29/07/21 (v0.5.2) - Merged PR by ONLYstcm which added a (configurable) timeout for connections. Thank you ONLYstcm.
  • 06/08/21 (v0.5.3) - Merged PR by ln-12 which added a connectSecure method to support WSS connection with the classic interface (host, port, path). Thank you!

arduinowebsockets's People

Contributors

adelin-mcbsoft avatar arnoson avatar calebbabin avatar chaliapin avatar gilmaimon avatar khoih-prog avatar ln-12 avatar onlystcm avatar robinvandenhurk avatar shajanjp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduinowebsockets's Issues

Not able to connect to AWS API Gateway Websockets (ESP8266)

Connecting to AWS API Gateway Websockets
Without fingerprint
-- Connection Closed ([$disconnect] getting called in Cloudwatch logs)
Reason: 1002

With fingerprint
-- No response on serial (No API is getting called)

I am able to connect to the websocket server from cmd.

What might be the issue here?

WebSocket is already in CLOSING or CLOSED state.

I'm not sure I'm doing this right. I'm want to send a stream of co-ordinates from the browser and drive a servo based on them, I get one though and then the browser error shown in the subject line above. Code pasted below.

Maybe auto client = server.accept(); should be outside the loop?

#include <ArduinoWebsockets.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer webserver(80);

using namespace websockets;
WebsocketsServer server;

void setup() {
  Serial.begin(115200);
  
  // Connect to wifi
  WiFi.begin(ssid, password);

  // Wait some time to connect to wifi
  for(int i = 0; i < 15 && WiFi.status() != WL_CONNECTED; i++) {
      Serial.print(".");
      delay(1000);
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());   //You can get IP address assigned to ESP
  
  webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html_gz, sizeof(index_html_gz));
    response->addHeader("Content-Encoding", "gzip");
    request->send(response);
  });
  
  webserver.begin();
  server.listen(83);
  Serial.print("Is server live? ");
  Serial.println(server.available());
}

void loop() {
  auto client = server.accept();
  if(client.available()) {
    Serial.println("client.available");
    auto msg = client.readBlocking();
	
    // log
    Serial.print("Got Message: ");
    Serial.println(msg.data());
  }
}

I have a few Newbie Question

I am new to Arduino and have a few questions:

  1. An I right to say that the websocket code is to run on the arduino ?
  2. What ESP module must I use ? Is NodeMCU ESP32 compatible ?

Thank you.

Times out?

Nice library & easy to use.
I have a websocket "bridge" (node-red) set up on a remote server, so I'm using the example client sketch on a ESP8266.
The ESP connects to the remote socket and works well, but after a period of time and inactivity, disconnects. If I re-boot the ESP it connects again. The remote server is not the cause, as other sockets remain connected indefinitely.

I'm new to the websocket world, so perhaps I'm overlooking the obvious? or, is there a built-in timeout in the library i might be able to change?

Event Callback not working ?

Hello, I'm using an esp32 (olimex esp32 gateway) as a websocket serve which a local html5 page connects to. Its wired via ethernet.
If the webpage crahes, I want it to reconnect on relaunch.

I'm using a flag to store the connection state of the websocket,
which is updated in the websocket event callback.
However these are not called on connection.
Serial.println("TEMP: connected"); is printing fine and javascript ws.onopen returns true.

Whats wrong?
How can I detect the websocket state here?

#include <ArduinoWebsockets.h>
#include <ETH.h>

bool eth_connected = false;
IPAddress local_IP(192, 168, 0, 50);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(9, 9, 9, 9);
IPAddress secondaryDNS(8, 8, 8, 8);

bool ws_connected = false;
using namespace websockets;
WebsocketsServer server;
WebsocketsClient client;

// Ethernet callbacks
void WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-ethernet");
      break;
    case SYSTEM_EVENT_ETH_CONNECTED:
      Serial.println("ETH Connected");
      break;
    case SYSTEM_EVENT_ETH_GOT_IP:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void onMessageCallback(WebsocketsMessage message) {
  Serial.print("Got Message: ");
  Serial.println(message.data());
}

void onEventsCallback(WebsocketsEvent event, String data) {
  if (event == WebsocketsEvent::ConnectionOpened) {
    Serial.println("Connnection Opened");
    ws_connected = true;
  } else if (event == WebsocketsEvent::ConnectionClosed) {
    Serial.println("Connnection Closed");
    ws_connected = false;
  } else if (event == WebsocketsEvent::GotPing) {
    Serial.println("Got a Ping!");
  } else if (event == WebsocketsEvent::GotPong) {
    Serial.println("Got a Pong!");
  }
}

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

  // Connect ethernet
  WiFi.onEvent(WiFiEvent);
  ETH.begin();
  ETH.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);

  server.listen(80);
  Serial.print("Is server live? ");
  Serial.println(server.available());
}

void loop() {
  if (eth_connected) {

  // ethernet connected, wait for websocket
    if (ws_connected == true) {
      if (client.available()) {
        WebsocketsMessage msg = client.readBlocking();
        Serial.print("Got Message: ");
        Serial.println(msg.data());
      }
    }

    else {
      Serial.println("no websocket client, waiting for connection ...");
      // Setup Callbacks
      client.onMessage(onMessageCallback);
      client.onEvent(onEventsCallback);
      // wait for client (blocking ...)
      client = server.accept();
      Serial.println("TEMP: connected");
    }
    // polling also needed to detect close state ?
    client.poll();
  }

  else {
    ETH.begin();
    ETH.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
    delay(3000);
  }
}

ESP32 panics if WebSocket doesn't exist

My ESP32 panics when I try to connect to a WebSocket that is not running. This is not what I'd expect, I would expect it to try connecting and if it fails it just tells me that it failed and doesn't make the ESP32 panic.

Everything works as expected once I start the WebSocket.

This issue is closely related to #10 but the conclusion you've come to in this comment is that it only happens when there's not a working WiFi connection but it also happens if the WebSocket is not running.

This is the full panic message:

[E][WiFiClient.cpp:282] setOption(): fail on fd 54, errno: 22, "Invalid argument"
[E][WiFiClient.cpp:365] write(): fail on fd 54, errno: 104, "Connection reset by peer"
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40122d4c  PS      : 0x00060830  A0      : 0x80123129  A1      : 0x3ffb1b70
A2      : 0x00000000  A3      : 0x3ffb1bcf  A4      : 0x00000001  A5      : 0x00000001
A6      : 0x00000000  A7      : 0xffffffa7  A8      : 0x00000000  A9      : 0x00000000
A10     : 0x00000000  A11     : 0x3ffc8660  A12     : 0x00000000  A13     : 0x3f4108b2
A14     : 0x00000000  A15     : 0x00000001  SAR     : 0x00000004  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000008  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff

Backtrace: 0x40122d4c:0x3ffb1b70 0x40123126:0x3ffb1b90 0x4016250a:0x3ffb1bc0 0x400d3daf:0x3ffb1bf0 0x400d3a36:0x3ffb1c10 0x400d466a:0x3ffb1d50 0x400d1e69:0x3ffb1f40 0x400d7f2b:0x3ffb1fb0 0x40088ea9:0x3ffb1fd0

Rebooting...

Cannot compile

Hi.
This library looks like exactly what I need but I cannot compile.
Initially I had a syntax error in "ws_common.hpp" with the "#include <string" I changed it to -> "#include <string.h>" and it was fixed.
But the next one I cannot fix it and it is related to "#include <memory.h>" inside the file "websockets_endpoint.hpp".

COMPILER ERROR ------->
In file included from ...Documents/Arduino/libraries/ArduinoWebsockets-0.4.9/src/tiny_websockets/client.hpp:6:0,
from ... Documents/Arduino/libraries/ArduinoWebsockets-0.4.9/src/ArduinoWebsockets.h:5,
from ...Documents/Arduino/libraries/ArduinoWebsockets-0.4.9/src/tiny_websockets/internals/websockets_endpoint.hpp:7:10: fatal error: memory.h: No such file or directory
#include <memory.h>
^~~~~~~~~~
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.
<-------END OF COMPILER ERROR

Please help !

Disconnect on large websocket message

Hello!

I'm trying to use this library on an ESP32 against API's that stream very large messages (~40k).

It works fine for the smaller messages, however as soon as a large message (should be) received a WebsocketsEvent::ConnectionClosed event is emitted and the connection is dropped.

I did some brief digging and it looks like the TCP connection stops being available(), but I'm not clear why.

This example code demonstrates the problem:

#include <ArduinoWebsockets.h>
#include <WiFi.h>

const char* ssid = "SSID";
const char* password = "PASSWORD";

const char* websockets_connection_string = "wss://ws.blockchain.info/inv";

using namespace websockets;

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

WebsocketsClient client;

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("ConnectionOpened");
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("ConnectionClosed");
    } else if(event == WebsocketsEvent::GotPong) {
        Serial.println("GotPong");
    }
}

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

    WiFi.begin(ssid, password);
    for(int i = 0; i < 10 && WiFi.status() != WL_CONNECTED; i++) {
        Serial.print(".");
        delay(1000);
    }

    client.onMessage(onMessageCallback);
    client.onEvent(onEventsCallback);

    client.setCACert(nullptr);
    client.connect(websockets_connection_string);

    // Works - results in "GotPong"
    client.ping();

    // Works - results in "Got Message: {"op":"pong"}"
    client.send("{\"op\":\"ping\"}");

    // FAILS - results in "ConnectionClosed"
    // This will cause ~40k of data to be returned down the websocket
    client.send("{\"op\":\"ping_block\"}");
}

void loop() {
    client.poll();
}

Any help very much appreciated.

[E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"

Describe the bug
Strange warning when connecting to a websocket server:
[E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"

To Reproduce
Just connect to a websocket server as shown in the examples.

Expected behavior
This warning is unexpected...

Code
Should be able to reproduce with the given examples.

Additional context
ESP32, framework-arduinoespressif32 2.10004.191002 (1.0.4)

Library example is not compiling

Describe the bug
I have just downloaded the latest version of the library on Arduino IDE.

I am trying to complile the example "Minimal Esp8266 Websockets Client" sketch in a NodeMCU board and I am receiving "Error compiling for board NodeMCU 1.0 (ESP-12E Module)."

Is the library compatible with NodeMCU 1.0 board?

Problem using the client and server code from within an Arduino library

Hi Gil, I am using your Arduino webSockets library with both the client and server running on an ESP32 Wroom-32 dev board in a similar manner to denden4444 described in issue #35. I have found the library really easy to use – it seems to have all the features I shall ever need. You have done a good job in writing this library. I am using the library to interface to my own local cloud server running on a Linux system where the code there is node.js. Initially I developed the Arduino code using inline code and it works perfectly.
In simple terms, the ESP board send a simple message to my local cloud to register itself and thereafter commands are sent from the cloud server to the ESP board to carry out various functions. All of this works. Your library is excellent.
I then wanted to use the same code in another application so I put the same client + server code in a library. The client component works perfectly but the server code does not work. When calling socket_server. available () function from within the library I always get a response that that server is not running. I have developed a test application which has the combined inline code and the library code and you can switch between the inline code and the library code by setting an integer to an appropriate value. Can you advise how I can try and determine the source of the problem?

I am happy to let you have the test code to illustrate the problem.

The board I am using is an ESP32 Wroom-32 dev board.
The library version I am using is 0.4.12 – the latest as of 17 October 2019.
I have a simple test harness in node.js for the local cloud function which I can also provide but I have also done some testing using netcat in Linux (i.e. the nc command).

Error compiling esp8266 client example

Hi Gil

I am experiencing a compile error ..
`
In file included from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/internals/ws_common.hpp:47:0,

             from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/message.hpp:3,

             from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/ArduinoWebsockets.h:4,

             from C:\Users\den\Documents\Arduino\libraries\arduino_290866\examples\Esp8266-Client\Esp8266-Client.ino:19:

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp: In member function 'void websockets::network::SecuredEsp8266TcpClient::setInsecure()':

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp:18:20: error: 'class WiFiClientSecure' has no member named 'setInsecure'

   this->client.setInsecure();

                ^

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp: In member function 'void websockets::network::SecuredEsp8266TcpClient::setFingerprint(const char*)':

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp:22:20: error: 'class WiFiClientSecure' has no member named 'setFingerprint'

   this->client.setFingerprint(fingerprint);

                ^

exit status 1
Error compiling for board Generic ESP8266 Module.
`

Could you please shed some light ?

Kind regards

Den

Multiple polls for 1 websocket client when using firefox as client

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

Using client.send() outside the loop (FireFox client incompatibility)

Hi. This might be more of a programming question again but...

Something like this works:

void delete_all_faces() {
  delete_face_all_in_flash_with_name(&st_face_list);
}
void handle_message(WebsocketsMessage msg) {
  if (msg.data() == "delete_all") {
    delete_all_faces();
    g_state = DELETE_ALL;
  }
}
void loop() {
   auto client = socket_server.accept();
   client.onMessage(handle_message);
   while (client.available()) {
      client.poll();
      switch (g_state) {
         case DELETE_ALL:
         client.send("All Faces Deleted");
         break;
         case ...
      }
   }
}

But I would prefer to send the message from the delete_all_faces function something like this...

void delete_all_faces() {
  delete_face_all_in_flash_with_name(&st_face_list);
  client.send("All Faces Deleted");
}
void handle_message(WebsocketsMessage msg) {
  if (msg.data() == "delete_all") {
    delete_all_faces();
  }
}
void loop() {
  auto client = socket_server.accept();
  client.onMessage(handle_message);
  while (client.available()) {
    ...
  }
}

Is it possible to make 'client' accessible outside the loop?

How to use the payload (message.data())

Hi Gil

Both server and client are working great so far.
I would like to replace the existing websockets library I have been using with your one.

For this I need to know how to use message.data() and what it is .. array struct etc and what format the data is in ?

In the previous library I was working with a payload array and am doing comparisons like :
if (payload[0] == '#') {

If you would be so kind as to expand on this a little it would save me oodles of time in switching my code over to start using and and use your awesome library.

I love the way it has very granular control.

I'm about to start on creating a client and server in one sketch for testing.Will update you on progress too.

I look forward to your reply.

Den

webSockets client and server on same ESP ?

Hello Gil

This looks like an awesome alternative to other libraries, and I'm quite excited to try it ;-)

I just need to know the following please :

  1. I need to have the server and client on the same ESP. is this possible and if so could you kindly explain how or provide an example ?
    Please see attached pic for reference.

  2. I would like to enable to disable the connection(client and/or server) when desired/required, independently of eachother.
    For example (pseudo code) :
    client enable
    do something
    client disable
    and same as above for server

  3. Are you able to call (and control - disable/enable) client and/or server from anywhere other than the main loop ?

Really looking forward to your reply

Kind regards

Den

websockets client and server in one

Create a custom Wiki

Currently there is a lot of info in the TinyWebsockets Wiki but no one seems to arrive there.

  1. The wiki should be moved/copied to this project as it is the main (and only) user of TinyWebsockets
  2. The examples should be adopted to Arduino environment
  3. GitHub pages for the wiki will help as well

How To Make Server Stay Connected to Client, Send INT Value?

Hi Gil...

This library is GREAT!!! Much needed. All the previous ones seemed very complex, especially for noobs like me. ;)

How would I use your library to create a server that just sends out the contents of an INT variable to connected clients every second, and doesn't disconnect the client?

Thanks!

--
Jim

Websocketclient disconnected from websocketserver

Describe the bug
Websocketclient is disconnected from websocketserver after client get a ping from server

To Reproduce
Library : 0.4.11
Board : NodeMCU
Steps to reproduce the behavior.

Expected behavior
I just hope the client doesn't disconnect from server

Additional context
When this first happens, I thought it was because of a bug of the library, but i realized that the websocketserver makes a ping to the client when it receives a connection, so I decided to supress this behavior. After doing this, the websocketclient worked as expected, but i have no idea of what am i doing wrong. I suppose that i should modify the code when the client receives a Ping, something like answer with a pong, but i am not sure

WSS Server on ESP32

Hi there,
first, thank you for doing this, it seems a solid library to me.

My question: I didn’t see any examples of a secured websocket server for esp32 or any other, did I miss something or isnt there a way yet?

Thank you

connect() timeout

Describe the bug
Infinite connection process if wifi is not connected

To Reproduce

  • latest library
  • ESP32

The connection process is not timed out if wifi lost the connection or wifi was not connected.
Usually wifi gets DISCONNECTED status after Websocket loses the connection, so the connection process stacks ESP

ESP8266/ESP32 error in internal receive

First described in this issue #2.

When continusly sending and receiving messages (with no/very-short delays) on esp8266 a message with bad values is read (opcode and fin makes no sense).

Does the issue occurs on ESP32?

available() not returning true

In version 0.3.1 and using the following code in a loop, after some random time (sometimes a long time) available() will return false, and bConnected will return true. Yet in the next loop around available is still false. The project in question is constantly sending and receiving websocket data until this problem occurs.

if(m_objWebsocketClient.available()) {
  m_objWebsocketClient.poll();
} else {    
  bConnected = m_objWebsocketClient.connect(m_sTCI_server, port, "/");
}

Error compiling ESP8266 server example

Hi Gil

ESP8266 server example won't compile .. (similar issues to my previous post about the client example not compiling.
`
In file included from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/internals/ws_common.hpp:47:0,

             from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/message.hpp:3,

             from C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/ArduinoWebsockets.h:4,

             from C:\Users\den\AppData\Local\Temp\arduino_modified_sketch_512897\Esp8266-Server.ino:20:

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp: In member function 'void websockets::network::SecuredEsp8266TcpClient::setInsecure()':

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp:18:20: error: 'class WiFiClientSecure' has no member named 'setInsecure'

   this->client.setInsecure();

                ^

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp: In member function 'void websockets::network::SecuredEsp8266TcpClient::setFingerprint(const char*)':

C:\Users\den\Documents\Arduino\libraries\arduino_290866\src/tiny_websockets/network/esp8266/esp8266_tcp.hpp:22:20: error: 'class WiFiClientSecure' has no member named 'setFingerprint'

   this->client.setFingerprint(fingerprint);

                ^

exit status 1
Error compiling for board Generic ESP8266 Module.

Hope you can help

Kind regards

Den
`

ESP8266 crashes when is receiving data from websocketserver

Describe the bug
I am using your library to receive a JSON file from a websocketserver. When it receive the file, it starts printing hexadecimal numbers and after two seconds aproximately the esp8266 restarts.

To Reproduce
Version : 0.4.11
Board : NODEMCU
Only using this library

Expected behavior
I expect to receive the json file, wich is received as a string, and later i want to print it By using serial library

Additional context
I supposed that this problem was related to the receive buffer size, so I execute the same code, but receiving a short json file and it worked as expected, so I think the problem is not related to code.

Library does not handle server/network failure (disconnect basically).

Hi,

I'm using the code from the Client Example for an SSL server.
Most of it works as expected, however - if I shutdown the WebSocket server I'm connected to or even disconnect the network, no event is being triggered.
Surprisingly, even if i call client.available() it returns true, even though the server is shut down or there's no network connection to it...

I'm using an ESP-WROOM-32 board if and an NGinx WebSocket server. The socket server works without any issue with any browser client (tested EDGE, Firefox, Chrome) and these browsers successfully report a server disconnect or so.

As told, code is the one from the client example:

#include <ArduinoWebsockets.h>
#include <WiFi.h>

const char* ssid = "WiFi Name"; //Enter SSID
const char* password = "WiFi Password"; //Enter Password
const char* websockets_server = "wss://url.com:443/ws/"; //server adress and port

using namespace websockets;

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("Connnection Opened");
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("Connnection Closed");
    } else if(event == WebsocketsEvent::GotPing) {
        Serial.println("Got a Ping!");
    } else if(event == WebsocketsEvent::GotPong) {
        Serial.println("Got a Pong!");
    }

    Serial.println("Event triggered...");
}

WebsocketsClient client;
void setup() {
    Serial.begin(115200);
    // Connect to wifi
    WiFi.begin(ssid, password);

    // Wait some time to connect to wifi
    for(int i = 0; i < 10 && WiFi.status() != WL_CONNECTED; i++) {
        Serial.println(".");
        delay(1000);
    }

    Serial.println("Connected to WiFi... probably.");

    // Setup Callbacks
    client.onMessage(onMessageCallback);
    client.onEvent(onEventsCallback);
    
    // Connect to server
    client.connect(websockets_server);

    // Send a message
    client.send("This is a nice little message sent from ESP32.");
}

void loop() {
  if (client.available()) {
    client.poll();
  } else {
    Serial.println("OOPS!! Client Disconnected...");
    delay(5000);
  }
}

If there's any detail I can help you with to debug this issue, just let me know.
All the best,
A.

How to handle multiple clients from server side ?

Hi Gil

Part of migrating my existing code to use your code involves handling multiple clients from the server side.

Is this possible and how do you handle this ?
Specifically :
How do you handle multiple clients and replies to each individual client ?
How do you identify each in turn and their specific data back and forth ?

Kind regards
Den

websocket and client on same server - possible bug

Hi Gil

Hope all's well with you.

As you may recall I have been testing your websockets on the ESP8266 and the tests have been good so far.
I'm hoping you could possibly identify/clarify some strange anomalies.
I am running both client and server on the same ESP8266.

Please refer to this image:
websockets client and server in one
A is a client (web browser) and needs to stay connected all the time until A decides it wants to disconnect
B is the ESP running both client and server.
When B receives a certain message , B fires up the websocket client portion and as w ebsocket client establishes a connection with C (C is running as a websockets server)
The above happen successfully (YAY ;-)) BUT
after B closes the connection (client disconnect) with C , the connection of A to B is lost. :-(
I have tried to set B not to close the connection to C ( no disconnect) but the same behavior occurs between A and B.
So I end up having to refresh the browser at A which re-establishes the connection from A to B.

Could you possibly shed some light as to how or where I could check and fix this ?

I'm not sure if this your software that may be causing the following :
Sometimes base on the problem in point 1. above , I am unable to re-establish a browser and/or websocket connection from A to B .
Its seems like B just stops servicing browser and/or websocket requests and sometimes a ping even though the serial console is still responding quite fine.
Any thoughts ?

Kind regards
Den

Memory exhaustion due to erroneous read size

I've found yet another bug while working on receiving extremely large websocket messages, however I'm not entirely convinced it's size related.

The same test program as from the previous large message issue should reproduce the problem:

#include <ArduinoWebsockets.h>
#include <WiFi.h>

const char* ssid = "SSID";
const char* password = "PASSWORD";

const char* websockets_connection_string = "wss://ws.blockchain.info/inv";

using namespace websockets;

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

WebsocketsClient client;

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("ConnectionOpened");
    }
}

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

    WiFi.begin(ssid, password);
    for(int i = 0; i < 10 && WiFi.status() != WL_CONNECTED; i++) {
        Serial.print(".");
        delay(1000);
    }

    client.onMessage(onMessageCallback);
    client.onEvent(onEventsCallback);

    client.setCACert(nullptr);
    client.connect(websockets_connection_string);

    // Results in total memory exhaustion, regardless of the amount of free memory available
    // ESP Panics
    client.send("{\"op\":\"ping_block\"}");
}

void loop() {
    client.poll();
}

I obtained an ESP32 WROVER module with 8mb of ram, which I know all the messages should easily fit into. At first I thought the allocator was failing to use the external memory as it carried on crashing, but after some digging it's revealed an odd bug.

It seems that the following segment of code in websockets_endpoint.cpp is the cause of the memory exhaustion:

uint32_t numReceived = socket.read(buffer, to_read);
for (uint64_t i = 0; i < numReceived; i++) {
data[done_reading + i] = static_cast<char>(buffer[i]);
}

Inserting a print statement to show the size of numReceived reveals normal behaviour right up until the crash, at which point the value of numReceived is set to the maximum value for uint32_t (4294967295) and the loop reads garbage data until the device runs out of memory.

Changing uint32_t to uint64_t for the return of client.read() resulted in the max value for uint64_t being returned instead.

This is a log & backtrace of the above program running, with websockets_endpoint.cpp patched to print out the size of numReceived:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:852
load:0x40078000,len:8424
load:0x40080400,len:5880
entry 0x4008069c
.[E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"
ConnectionOpened
size: 512
size: 512
size: 512
size: 512
size: 512
size: 512
size: 512
size: 498
size: 512
size: 512
size: 512
size: 512
size: 512
size: 512
size: 512
size: 498
size: 512
size: 512
size: 512
size: 512
size: 326
size: 512
size: 512
size: 512
size: 172
size: 512
size: 512
size: 373
size: 4294967295
Guru Meditation Error: Core  1 panic'ed (LoadStoreError). Exception was unhandled.
Core 1 register dump:
PC      : 0x401421ca  PS      : 0x00060c30  A0      : 0x8014228c  A1      : 0x3ffb1bf0
0x401421ca: websockets::internals::readData[abi:cxx11](websockets::network::TcpClient&, unsigned long long) at /Users/jonty/code/esp/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/shared_ptr_base.h:659

A2      : 0x00000575  A3      : 0x3ffbb9b8  A4      : 0x00000ff2  A5      : 0xffffffff
A6      : 0x3ffb1e44  A7      : 0x00000000  A8      : 0x0001f627  A9      : 0x40000000
A10     : 0x00000000  A11     : 0x000000fe  A12     : 0x3ffb1c0c  A13     : 0x00000000
A14     : 0x00000ff2  A15     : 0x3ffe636c  SAR     : 0x00000004  EXCCAUSE: 0x00000003
EXCVADDR: 0x40000000  LBEG    : 0x40098705  LEND    : 0x40098715  LCOUNT  : 0xffffffff
0x40098705: strlen at /home/jeroen/esp8266/esp32/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/strlen.S:84

0x40098715: strlen at /home/jeroen/esp8266/esp32/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/strlen.S:96


Backtrace: 0x401421ca:0x3ffb1bf0 0x40142289:0x3ffb1e30 0x401433fd:0x3ffb1e80 0x4013f7e3:0x3ffb1ef0 0x4013bdfa:0x3ffb1f90 0x401207e1:0x3ffb1fb0 0x4008b799:0x3ffb1fd0
0x401421ca: websockets::internals::readData[abi:cxx11](websockets::network::TcpClient&, unsigned long long) at /Users/jonty/code/esp/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/shared_ptr_base.h:659

0x40142289: websockets::internals::WebsocketsEndpoint::_recv() at /Users/jonty/code/esp/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/shared_ptr_base.h:659

0x401433fd: websockets::internals::WebsocketsEndpoint::recv() at /Users/jonty/code/chain/components/arduino/libraries/ArduinoWebsockets/src/websockets_endpoint.cpp:312

0x4013f7e3: websockets::WebsocketsClient::poll() at /Users/jonty/code/chain/components/arduino/libraries/ArduinoWebsockets/src/websockets_client.cpp:499

0x4013bdfa: loop() at /Users/jonty/code/chain/main/main.cpp:93

0x401207e1: loopTask(void*) at /Users/jonty/code/chain/components/arduino/cores/esp32/main.cpp:19

0x4008b799: vPortTaskWrapper at /Users/jonty/code/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)

to_read is always a sane value, so I also tried adding an extra check to the read loop to ensure that i <= to_read and while this prevented the memory exhaustion it resulted in being disconnected from the server shortly afterward, so clearly the session state is messed up.

This should be easily reproducible on an ESP32 with limited memory as the exhaustion trigger happens before any significant memory usage, although I've not tested this.

Let me know if you need any more information, or want me to test things.

Basic connection question

Hello, I would like to use this library to develop a websocketclient wich will communicate with a php laravel websocketserver.
This websocket server is currently running and comunicating with other websocket clients written in javascript.
new WebSocket(ws://192.168.1.12:6001);
Above is shown the way in wich javascript objects are being created (these objects can comunicate with the websocket server).
This is my question, when i call the connect method, I would like to pass the host, the port and the path independiently as shown below, in this case its pretty easy to identify the host and the port, but i have some doubts about which will be the correct path.
#define IP_ADDRESS "192.168.1.12"
#define PORT 6001
#define PATH "/"
websocket.connect(IP_ADDRESS, PORT, PATH);
I know this looks like a basic question, but i would like to know which is the correct answer.
Thanks in advance

Support Arduino UNO wifi rev 2

I'm trying to setup a websocket server on my Arduino UNO wifi rev 2, but as soon as I include ArduinoWebsockets to my script, I get a compilation error:

In file included from /.../Arduino/libraries/ArduinoWebsockets/src/tiny_websockets/message.hpp:3:0,
                 from /.../Arduino/libraries/ArduinoWebsockets/src/ArduinoWebsockets.h:4,
                 from /.../Arduino/distancemeterWifi/distancemeterWifi.ino:3:
/.../Arduino/libraries/ArduinoWebsockets/src/tiny_websockets/internals/ws_common.hpp:4:10: fatal error: string: No such file or directory
 #include <string>
          ^~~~~~~~
compilation terminated.
exit status 1

I'm fairly new to the programming language, so I have no clue what is causing this... Why is this importing "string" ?

Binary data not working

Looks like 0 chars in binary package terminats packed.

Or msg.data().length() is not working ...

client.send() does not mask the messages

Hi Gil,

Me again.
I want to bring to your attention the following situation:

Messages that go through client.send() are sent in plain-text, unmasked (see more about websocket masking).
However, it seems that the library understands and successfully decodes the received masked messages.

How I tested:

  1. When you use the HTML5 send() method to send a message, the messages are automatically masked by the browser and sent to the server.
  2. At the server, the messages come masked, and the server decodes it. In PHP, I'm using the following function to unmask:
/**
     * @method  unmask
     * @param   $text   string
     * @return  string
     * @desc    Unmask incoming framed message
     */
    private function unmaskReceivedData($text) {
        $length = ord($text[1]) & 127;

        if($length == 126) {
            $masks = substr($text, 4, 4);
            $data = substr($text, 8);
        } elseif($length == 127) {
            $masks = substr($text, 10, 4);
            $data = substr($text, 14);
        } else {
            $masks = substr($text, 2, 4);
            $data = substr($text, 6);
        }

        $text = '';
        for ($i = 0; $i < strlen($data); ++$i) {
            $text .= $data[$i] ^ $masks[$i%4];
        }
        return $text;
    }

AFAIK, this method is being written according to the RFC standards.
From there, on my server I decode (unmask) the message, process it, then mask it again to broadcast to all the connected clients.

For masking I'm using the following code:

    private function maskSentData($text)  {
        $b1 = 0x80 | (0x1 & 0x0f);
        $length = strlen($text);

        $header = '';

        if($length <= 125)
            $header = pack('CC', $b1, $length);
        elseif($length > 125 && $length < 65536)
            $header = pack('CCn', $b1, 126, $length);
        elseif($length >= 65536)
            $header = pack('CCNN', $b1, 127, $length);
        return $header . $text;
    }

When I broadcast it, the browser and the ESP32 receive it successfully.

However, when I try to send a message through libraries client.send(text) method, all the messages received on the server are plain, not masked in any way (and of course, the servers unmask method fails).

Just a note to this: Something might had happen recently (through an update or so) because few weeks ago (when we had issue #14 ), this bug didn't happen (though I cannot identify where the change could come from...).

You know the library as better as anyone, so I'm pretty sure you can shed some light here.

If you need any more info from me, just let me know.
Hope it helps,

Thanks,
Best,
A.

ESP32 panics when ArduinoWebsockets initiates a websocket connection

My ESP32 panics when ArduinoWebsockets initiates a websocket connection.

Code running on ESP32:

#include <Arduino.h>
#include <WiFiManager.h>
#include <ArduinoWebsockets.h>

WiFiManager wifiManager;

using namespace websockets;
WebsocketsClient client;

static const char SERVER[] = "ws://192.168.1.149"; // my laptop's IP

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("Connnection Opened");
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("Connnection Closed");
    } else if(event == WebsocketsEvent::GotPing) {
        Serial.println("Got a Ping!");
    } else if(event == WebsocketsEvent::GotPong) {
        Serial.println("Got a Pong!");
    }
}

void setup()
{
  Serial.begin(115200);
  wifiManager.autoConnect();

  // Setup Callbacks
  client.onMessage(onMessageCallback);
  client.onEvent(onEventsCallback);
  client.connect(SERVER);

  client.send("Hello");
  client.ping();
}

void loop()
{
  client.send(String(millis()));
  client.poll();
  delay(500);
}

On my laptop, I can see an incoming connection:

$ sudo nc -l 80 -vvvv
Listening on [0.0.0.0] (family 0, port 80)
Connection from espressif 62507 received!
GET / HTTP/1.1
Host: 192.168.1.149
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: MDEyMzQ1Njc4OWFiY2RlZg==
Sec-WebSocket-Version: 13

But when I use websocat's server:

sudo websocat -s 80 -vvvv
Listening on ws://127.0.0.1:80/
[INFO  websocat::lints] Auto-inserting the line mode
[DEBUG websocat] Done third phase of interpreting options.
[DEBUG websocat] Done fourth phase of interpreting options.
[DEBUG websocat] Preparation done. Now actually starting.
[INFO  websocat::sessionserve] Serving Message2Line(WsServer(TcpListen(V4(127.0.0.1:80)))) to BroadcastReuser(Line2Message(Stdio)) with Options { websocket_text_mode: true, websocket_protocol: None, websocket_reply_protocol: None, udp_oneshot_mode: false, unidirectional: false, unidirectional_reverse: false, exit_on_eof: true, oneshot: false, unlink_unix_socket: false, exec_args: [], ws_c_uri: "ws://0.0.0.0/", linemode_strip_newlines: false, linemode_strict: false, origin: None, custom_headers: [], custom_reply_headers: [], websocket_version: None, websocket_dont_close: false, one_message: false, no_auto_linemode: false, buffer_size: 65536, broadcast_queue_len: 16, read_debt_handling: Warn, linemode_zero_terminated: false, restrict_uri: None, serve_static_files: [], exec_set_env: false, reuser_send_zero_msg_on_disconnect: false, process_zero_sighup: false, process_exit_sighup: false, socks_destination: None, auto_socks5: None, socks5_bind_script: None, tls_domain: None, tls_insecure: false, max_parallel_conns: None, ws_ping_interval: None, ws_ping_timeout: None }

The ESP32 will die:

*WM: [1] AutoConnect 
*WM: [2] ESP32 event handler enabled 
*WM: [2] Connecting as wifi client... 
*WM: [1] STA static IP:
*WM: [2] setSTAConfig static ip not set 
*WM: [3] WIFI station disconnect 
*WM: [1] Connecting to saved AP: XXXXXXXX
*WM: [3] Using Password: XXXXXXXX
*WM: [3] WiFi station enable 
*WM: [1] connectTimeout not set, ESP waitForConnectResult... 
*WM: [2] Connection result: WL_CONNECTED
*WM: [3] lastconxresult: WL_CONNECTED
*WM: [1] AutoConnect: SUCCESS 
*WM: [1] STA IP Address: 192.168.1.29
[E][WiFiClient.cpp:282] setOption(): fail on fd 54, errno: 22, "Invalid argument"
[E][WiFiClient.cpp:365] write(): fail on fd 54, errno: 104, "Connection reset by peer"
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x4012d2c0  PS      : 0x00060830  A0      : 0x8012d721  A1      : 0x3ffb1b90  
A2      : 0x00000000  A3      : 0x3ffb1bef  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00000000  A7      : 0xffffffa7  A8      : 0x00000000  A9      : 0x00000000  
A10     : 0x00000000  A11     : 0x3ffc8dcc  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060e20  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000008  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

Backtrace: 0x4012d2c0:0x3ffb1b90 0x4012d71e:0x3ffb1bb0 0x40173692:0x3ffb1be0 0x400dc65b:0x3ffb1c10 0x400dc2e6:0x3ffb1c30 0x400dcefa:0x3ffb1d70 0x400d20ad:0x3ffb1f60 0x400e0abf:0x3ffb1fb0 0x4008b015:0x3ffb1fd0

Rebooting...

Sending two sets of data in the same connection

Me again. As part of the same set of projects I'm using face detection and recognition from this library: https://github.com/espressif/esp-who

I want to send images and also a message to the browser (for further actions) when a face is detected. I can do it like this which is working well:

(loop)
   //camera and detection stuff here
    if(detected==true){
      client.send("Face Detected");
      }
    client.sendBinary((const char *)_jpg_buf, _jpg_buf_len);
(/loop)
		ws.onmessage = message => {
                  if (typeof message.data === 'string'){
                    console.log("Face Detected")
                  }
                  if (message.data instanceof Blob){
		     var urlObject = URL.createObjectURL(message.data);
		     ws_img.setAttribute('src', urlObject);
                  }

I'm not sure this is the best way to separate the two sent items. Also if I can work out how to do it I want to send the mapping of the face instead of just a message which I'm guessing will be another blob.

Is this the best way of sending two different things to the client? I couldn't see a way of identifying messages as they are sent.

I'll get back to you on the other question soon.

use wired solution with Wiznet module on teensy

Your library looks great. It seems to be more updated than
https://github.com/PaulStoffregen/ArduinoWebsocketClient

I am hoping to use Websocket through the wizen module on a teensy 3.2 (Arduino compatible micro controller).
But the library I am currently using does not support SEC-Key but it looks yours does.

Do you think it would be possible to add support for the wiznet ethernet module?
Your wifi solution is great but I find a wired solution more secure for long term installations.

Thanks for any advice.

WSS Not working for some sites.

Using your example, I can connect to wss://echo.websocket.org but not wss://ws-feed.pro.coinbase.com, nor wss://api.bitfinex.com/ws/2.

I've tried with fingerprint and with client.setInsecure(), no luck.

Some logs:

14:19:08.149 -> connect ws...
14:19:08.149 -> [hostByName] request IP for: api.bitfinex.com
14:19:08.184 -> pm open,type:2 0
14:19:08.184 -> [hostByName] Host: api.bitfinex.com IP: 104.16.171.181
14:19:08.252 -> :ref 1
14:19:08.287 -> BSSL:_connectSSL: start connection
14:19:08.321 -> :wr 221 0
14:19:08.321 -> :wrc 221 221 0
14:19:08.356 -> :ack 221
14:19:08.391 -> :rn 536
.......................................
14:19:09.598 -> :rdi 32, 32
14:19:09.598 -> :c0 32, 43
14:19:09.632 -> BSSL:Connected!
14:19:09.632 -> :wr 180 0
14:19:09.632 -> :wrc 180 180 0
14:19:09.737 -> :ack 180
14:19:09.737 -> BSSL:read: failed
14:19:09.737 -> BSSL:read: failed
14:19:09.771 -> BSSL:read: failed
14:19:09.805 -> BSSL:read: failed
14:19:09.805 -> BSSL:read: failed
14:19:09.839 -> BSSL:read: failed
14:19:09.839 -> BSSL:read: failed
14:19:09.874 -> BSSL:read: failed
14:19:09.874 -> BSSL:read: failed
14:19:09.908 -> BSSL:read: failed
14:19:09.908 -> BSSL:read: failed
14:19:09.943 -> BSSL:read: failed
14:19:09.977 -> BSSL:read: failed
14:19:09.977 -> BSSL:read: failed
14:19:10.011 -> BSSL:read: failed
14:19:10.011 -> BSSL:read: failed
14:19:10.046 -> :rn 536
14:19:10.046 -> :rch 536, 173
14:19:10.080 -> :rch 709, 125

If I try connecting to the unsecured ones (ws://api.bitfinex.com/ws/2)

14:23:46.080 -> connect ws...
14:23:46.080 -> [hostByName] request IP for: api.bitfinex.com
14:23:46.115 -> pm open,type:2 0
14:23:46.149 -> [hostByName] Host: api.bitfinex.com IP: 104.16.175.181
14:23:46.183 -> :ref 1
14:23:46.218 -> :wr 159 0
14:23:46.218 -> :wrc 159 159 0
14:23:46.288 -> :ack 159
14:23:46.288 -> :rn 288
14:23:46.288 -> :wr 2 0
14:23:46.288 -> :wrc 2 2 0
14:23:46.323 -> :wr 2 0
14:23:46.323 -> :wrc 2 2 0
14:23:46.358 -> :ack 2
14:23:46.358 -> :rch 288, 332
14:23:46.358 -> :rcl
14:23:46.358 -> :abort
14:23:46.392 -> Connnection Closed

Any ideas?

Thanks a lot

How to handle disconnect or an error

What is the best way to reconnect after a disconnect or some error?

I tried the following but doesn't appear to be working.
void onEventsCallback(WebsocketsEvent event, String data) {
if(event == WebsocketsEvent::ConnectionClosed) {
client.connect("wss://ws-feed.pro.coinbase.com");
client.send("{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker"]}");
}

Instead is there any way to check if the connection is active in the loop() and reconnect from there?

Possible to stream with ArduinoJSON?

Hey!

This is a question. I'm using this lib together with https://arduinojson.org

My code currently looks like:

void onWsMsg(WebsocketsMessage message) {
  StaticJsonDocument<1024> doc;
  DeserializationError error = deserializeJson(doc, message.data());
  JsonObject obj = doc.as<JsonObject>();

and

void sendJson(JsonObject obj) {
  char output[2048];
  serializeJson(obj, output);
  client.send(output);
}

My question is if it would be possible to hook ArduinoWebsockets up directly with the stream functionality of https://arduinojson.org/v6/api/json/deserializejson/ and https://arduinojson.org/v6/api/json/serializejson/ and if so how I would do that.

Cheers!

ESP-32 panic when trying to connect to the old socket

Hi!

First of all, thanks for this lovely library!

I have found something that is similar to #25

I use https://github.com/websockets/wscat for my development. And start up a server.

The first time, client.connect works.
Also, if I never start the server, client.connect does not crash and I can stay in a client.available loop.

However, if I start the board, it successfully connects to the server. Then reboot the board (without wscat noticing) and it tries to connect to wscat that still thinks it's connected to the previous boot. Then the board crashes.

I have extracted the stacktrace:

PC: 0x400d2e18: WiFiClientRxBuffer::read(unsigned char*, unsigned int) at /home/lex/.arduino15/packages/esp32/hardware/esp32/1.0.4-rc1/libraries/WiFi/src/WiFiClient.cpp line 107
EXCVADDR: 0x00000008

Decoding stack results
0x400d2e18: WiFiClientRxBuffer::read(unsigned char*, unsigned int) at /home/lex/.arduino15/packages/esp32/hardware/esp32/1.0.4-rc1/libraries/WiFi/src/WiFiClient.cpp line 107
0x400d2ee9: WiFiClient::read(unsigned char*, unsigned int) at /home/lex/.arduino15/packages/esp32/hardware/esp32/1.0.4-rc1/libraries/WiFi/src/WiFiClient.cpp line 434
0x4015fcea: WiFiClient::read() at /home/lex/.arduino15/packages/esp32/hardware/esp32/1.0.4-rc1/libraries/WiFi/src/WiFiClient.cpp line 345
0x400e32af: websockets::network::GenericEspTcpClient ::readLine() at /home/lex/Arduino/libraries/ArduinoWebsockets/src/tiny_websockets/network/generic_esp/generic_esp_clients.hpp line 46
0x400e2fce: websockets::WebsocketsClient::connect(String, int, String) at /home/lex/Arduino/libraries/ArduinoWebsockets/src/websockets_client.cpp line 279
0x400d1ac5: loop() at /home/lex/Arduino/sketch_oct15a/sketch_oct15a.ino line 95
0x400e870d: loopTask(void*) at /home/lex/.arduino15/packages/esp32/hardware/esp32/1.0.4-rc1/cores/esp32/main.cpp line 19
0x40088dbd: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Board: Huzzah 32
Websockets: 0.4.11
Wscat: 2.2.1

Don't really know why it behaves differently when trying to connect to a non open port vs a port that I guess "thinks" it's open.

This will probably not cause any issue for me during production when I run with a real server but I would like to contribute to making this library rock-solid in any way I can.

Cheers!

client.sendBinary with camera stream crashing recent versions

For versions above 0.4.0 sending binary (video frames) is crashing in my script:

Cut down code on ESP32 (Arduino IDE)

void loop() {
  auto client = socket_server.accept();
  client.onMessage(handle_message);
  while (client.available()) {
    client.poll();
    fb = esp_camera_fb_get();
    client.sendBinary((const char *)fb->buf, fb->len);
    esp_camera_fb_return(fb);
    fb = NULL;
  }
}

JS in browser:

document.addEventListener("DOMContentLoaded", function(event) {
  var baseHost = document.location.origin;
  const WS_URL = "ws://" + window.location.host + ":82";
  const ws = new WebSocket(WS_URL);

  ws.onmessage = message => {
    if (message.data instanceof Blob) {
      var urlObject = URL.createObjectURL(message.data);
      view.src = urlObject;
    }
  };
});

It works great in 0.4.0 so I don't know if some code was changed for send.binary in later versions?

Crash report....

[D][WiFiClient.cpp:482] connected(): Disconnected: RES: 0, ERR: 128
[E][WiFiClient.cpp:365] write(): fail on fd 63, errno: 11, "No more processes"
[E][WiFiClient.cpp:365] write(): fail on fd 63, errno: 11, "No more processes"
[E][WiFiClient.cpp:365] write(): fail on fd 63, errno: 11, "No more processes"
[E][WiFiClient.cpp:365] write(): fail on fd 63, errno: 11, "No more processes"
[E][WiFiClient.cpp:365] write(): fail on fd 63, errno: 11, "No more processes"
abort() was called at PC 0x40136eeb on core 1

Backtrace: 0x40091408:0x3ffb1d20 0x40091639:0x3ffb1d40 0x40136eeb:0x3ffb1d60 0x40136f32:0x3ffb1d80 0x401362bf:0x3ffb1da0 0x401363ae:0x3ffb1dc0 0x40136365:0x3ffb1de0 0x400d575b:0x3ffb1e00 0x400d57b6:0x3ffb1e30 0x400d4b8a:0x3ffb1e60 0x400d3339:0x3ffb1e80 0x400d9be9:0x3ffb1fb0 0x4008d3a5:0x3ffb1fd0

Rebooting...

Decoding stack results
0x40091408: invoke_abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/panic.c line 155
0x40091639: abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/panic.c line 170
0x40136eeb: __cxxabiv1::__terminate(void ()()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 47
0x40136f32: std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 57
0x401362bf: __cxxabiv1::__cxa_throw(void, std::type_info*, void ()(void)) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc line 87
0x401363ae: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc line 54
0x40136365: operator new[](unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_opv.cc line 32
0x400d575b: websockets::internals::WebsocketsEndpoint::send(char const*, unsigned int, unsigned char, bool, bool, char const*) at C:\Users\Dude\Documents\Arduino\libraries\ArduinoWebsockets\src\websockets_endpoint.cpp line 367
0x400d57b6: websockets::internals::WebsocketsEndpoint::send(char const*, unsigned int, unsigned char, bool) at C:\Users\Dude\Documents\Arduino\libraries\ArduinoWebsockets\src\websockets_endpoint.cpp line 321
0x400d4b8a: websockets::WebsocketsClient::sendBinary(char const*, unsigned int) at C:\Users\Dude\Documents\Arduino\libraries\ArduinoWebsockets\src\websockets_client.cpp line 396
0x400d3339: loop() at C:\Users\Dude\Documents\Arduino\CameraWebServerWeChatWebSockets/CameraWebServerWeChatWebSockets.ino line 358
0x400d9be9: loopTask(void*) at C:\Users\Dude\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3-rc1\cores\esp32\main.cpp line 19
0x4008d3a5: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143

ESP32: Investigation necessarry: is SSL CA/Chain really validated without providing a CA ?

Hi Gil,

Me again (and again, and again). :D
I just want to bring to your attention and old discussed issue, regarding the SSL Certificate and Handshaking, on ESP32.

Situation 1: When not using any sort of certificate but using an WSS (secure) server/URL, the debug messages report that the certificate is verified, though I don't provide any CA resource (as browsers do).

Situation 2: When I provide a good CA along with the client.setCAcert() method, the verification passes as well.

(messages for both situation 1 and 2):

[V][ssl_client.cpp:53] start_ssl_client(): Free internal heap before TLS 277372
[V][ssl_client.cpp:55] start_ssl_client(): Starting socket
[V][ssl_client.cpp:90] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:99] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:112] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:177] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:192] start_ssl_client(): Performing the SSL/TLS handshake...
[V][ssl_client.cpp:213] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:222] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:237] start_ssl_client(): Free internal heap after TLS 236048

Situation 3: However, when I provide a wrong CA resource (e.g. an invalid CA root cert.), the handshaking fails (as it should).

The question is: When not providing a CA resource (Situation 1), does the library verifies indeed the certificate in any way or not? Does it connect remotely to the CA Roots and verifies it? I guess this ssl_client is inherited by Espressifs library...

I tested the above situations with an LetsEncrypt certificate along its roots ( https://letsencrypt.org/certificates/ ).

Many thanks,
Best,

A.

Set custom headers on WSS connection

Hi!!!, first of all, the library is great!!!!, and sorry for my english.
I am working with a server that requires a token in connection header ("Authorization: JWT [token]") to accept the connection of websocket. Is possible to add a custom header in header request?

How to set server to non-blocking while in main loop ?

Hi Gil

How do you set the server to be non-blocking in the main loop , in other words to allow other code/functions to run ?
For example I have the following :

void loop() {

  server.handleClient();                      // run the web server
  //websockets server
  WebsocketsClient client = wsserver.accept();
  if (client.available()) {
    WebsocketsMessage msg = client.readBlocking();

    // log
    Serial.print("Got Message: ");
    Serial.println(msg.data());
  }

  // return echo
  client.send("Echo: " + msg.data());

  // close the connection
  client.close();
}//endof if client.available


//end of webSocket Server

SOME_OTHER_FUNCTION();
SOME_OTHER_FUNCTION_TWO();
//etc
//start from beginning of loop again
}

Look forward to your reply as always :-)

Den

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.