Giter Club home page Giter Club logo

mwebsockets's Introduction

μWebSockets

arduino-library-badge Build Status CodeFactor Grade GitHub

Simple to use implementation of WebSockets for microcontrollers.

List of supported IDEs:

List of supported MCUs:

  • ATmega328P
  • ATmega2560
  • Renesas RA4M1 (ARM Cortex-M4)
  • SAMD21 (ARM Cortex-M0+)
  • STM32 (ARM Cortex-M)
  • ESP8266
  • ESP32-WROOM-32D

WebSocketServer compatible browsers:

  • Chrome
  • Edge
  • Firefox
  • Opera

The Autobahn|Testsuite reports for server and client
Some tests will never pass just because of memory lack in ATmega family.

Table of contents

Requirements

  • Development board (confirmed working, other boards may or may not work):
    • Arduino Uno (ATmega328P)
    • Arduino Pro Mini (ATmega328P)
    • Arduino Mega2560
    • Arduino Uno R4 Minima/WiFi (ARM Cortex-M4)
    • Arduino Zero / SAMD21 M0 (ARM Cortex-M0)
    • STM Nucleo-64 (ARM Cortex-M)
    • WeMos D1 mini (ESP8266)
    • NodeMCU v3 (ESP8266)
    • ESPDUINO-32 (ESP32-WROOM-32D)
  • Ethernet module or shield (confirmed working):
    • Arduino Ethernet Shield (W5100)
    • Arduino Ethernet Shield 2 (W5500)
    • WizNet W5500 module
    • ENC28j60
  • Libraries:

Installation

Use Arduino Download Manager or follow this guide.

config.h

Change the following definition if you use a different network controller:

...

#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_ENC28J60
NETWORK_CONTROLLER_WIFI

ETHERNET_CONTROLLER_W5X00 stands for the official Arduino Ethernet library.

Uncomment these if you want additional information on the serial monitor:

//#define _DEBUG
//#define _DUMP_HANDSHAKE
//#define _DUMP_FRAME_DATA
//#define _DUMP_HEADER

Increase the following value if you expect big data frames (or decrease for devices with a small amount of memory).

constexpr uint16_t kBufferMaxSize{ 256 };

Physical connection

If you have a WeMos D1 in the size of Arduino Uno simply attaching a shield does not work. You have to wire the ICSP on an Ethernet Shield to proper pins.

Ethernet Shield
(W5100/W5500)
Arduino
Pro Mini
WeMos D1
(ICSP) MISO PIN 12 D12 / MISO
(ICSP) MOSI PIN 11 D11 / MOSI
(ICSP) SCK PIN 13 D13 / SCK
(SS) PIN 10 PIN 10 D10 / SS
W5500 /
ENC28j60
Arduino Uno /
Pro Mini
Arduino
Mega2560
MISO PIN 12 PIN 50
MOSI PIN 11 PIN 51
SCS PIN 10 PIN 53
SCLK PIN 13 PIN 52

Usage examples

Server

#include <WebSocketServer.h>
using namespace net;

WebSocketServer server{3000};

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  server.onConnection([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino server!" };
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));

    ws.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                 const char *reason, uint16_t length) {
      // ...
    });
    ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                   const char *message, uint16_t length) {
      // ...
    });
  });

  server.begin();
}

void loop() {
  server.listen();
}

Verify clients

// verifyClient callback is called for every header during handshake
// (except for those required by protocol, like "Connection", "Upgrade" etc.)
server.begin([](const IPAddress &ip, const char *header, const char *value) {
  // verify ip ...

  // verify "Origin" header:
  if (strcmp_P(header, (PGM_P)F("Origin")) == 0)
    if (strcmp_P(value, (PGM_P)F("file://")) == 0) return false;

  return true;
});

Subprotocol negotiation

// If you won't pass callback for `protocolHandler` then server will use the
// first requested subprotocol if any
wss.begin(nullptr, [](const char *protocols) {
  // iterate csv protocols and return the one that is supported by your server
  // or nullptr to ignore
});

// You can check client protocol in other callbacks
wss.onConnection([](WebSocket &ws) {
  const auto protocol = ws.getProtocol();
  // ...
  }
});

Node.js server examples here

Client

#include <WebSocketClient.h>
using namespace net;

WebSocketClient client;

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  client.onOpen([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino client!" };
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });
  client.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                   const char *reason, uint16_t length) {
    // ...
  });
  client.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                     const char *message, uint16_t length) {
    // ...
  });

  client.open("echo.websocket.org", 80);
}

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

Chat

Node.js server on Raspberry Pi (/node.js/chat.js)

Browser client (/node.js/chat-client.htm)

Arduino Uno client (/examples/chat/chat.ino)

More examples here

Approx memory usage

simple-client.ino example (without debug output, 128 bytes data buffer)

Ethernet.h (W5100 and W5500)

Board Program space Dynamic memory
Arduino Uno 24 648 bytes (76%) 829 bytes (40%)
Arduino Mega2560 25 640 bytes (10%) 857 bytes (10%)
Arduino Pro Mini 24 648 bytes (80%) 829 bytes (40%)
Arduino Zero 30 596 bytes (11%) 3 056 bytes (9%)
Arduino Uno R4 Minima 63 860 bytes (24%) 3 620 bytes (11%)

EthernetENC.h (ENC28j60)

Board Program space Dynamic memory
Arduino Uno 31 062 bytes (96%) 1 406 bytes (68%)
Arduino Mega2560 32 074 bytes (12%) 1 406 bytes (17%)
Arduino Pro Mini 31 062 bytes (101%) 1 406 bytes (68%)
Arduino Zero 36 796 bytes (14%) 3 684 bytes (11%)

WiFi

Board Program space Dynamic memory
Generic ESP8266 286 328 bytes (29%) 27 356 bytes (33%)
WeMos D1 mini 286 328 bytes (27%) 27 356 bytes (33%)
NodeMCU 286 328 bytes (27%) 27 356 bytes (33%)
Arduino Uno R4 WiFi 57 596 bytes (21%) 4 492 bytes (13%)

Known issues

...

License

mwebsockets's People

Contributors

per1234 avatar prenone avatar skaarj1989 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

mwebsockets's Issues

webSocket : bug with firefox 7.1 client and arduino server

Following a bug UPGRADE_REQUIRED encountered with firefox 7.1 on the client side and arduino on the server side, I noticed that the "Connection" header was different from the other web browsers.
Firefox : Connection: keep-alive, Upgrade
others : Connection: Upgrade
To fix this problem, I modified line 255 of the WebSocketServer.cpp file this way:
if ((strcmp_P(value, (PGM_P)F("Upgrade")) != 0) && (strcmp_P(value, (PGM_P)F("keep-alive,")) != 0))
There is probably a more elegant and general correction to this bug.

MKR1000 and socket.io

Hello,

Can your library be used to communicate with a server created with nodejs + express + socket.io?
Can it be used with a MKR1000 and Wifi101?
Do you have examples using Wifi101?

Thank you very much for all your information.

Regards,

NETWORK_CONTROLLER switched by user

Hello, thank you very much for this library, i'm using it in my project and it works very well.

I'm building an ESP32 device with an angular client that talks with the controller on websocket and it works well over ethernet, over wifi and over softAP.
My device at boot load the configuration from SPIFFS and start.

What i'm trying to do now is to add the ability for the user to choose the connection type (Eth/softAP/Wifi), save it in config and reboot with the new configuration.

But i think it is not possible because NETWORK_CONTROLLER must be defined in the config.h and can't be changed later.
Any idea how i can do?

Thank you very much and sorry for my english.

_handleFrame slow

I am yet to thoroughly diagnose the issue, but preliminary findings suggest that _handleFrame, which is invoked via client.listen() in loop() is blocking and slow.

My application, which is running on a Arduino Mega 2560 R3 with a W5100 Ethernet Shield requires high levels of responsiveness.

'class net::WebSocketServer' has no member named 'getProtocol' - simple-server.ino not compiling

This seems to be a similar issue to what has been discussed previously, but currently I am trying to compile simple-server.ino via Arduino IDE v1.8.13. However when I compile, this line gets flagged:

const auto protocol = ws.getProtocol();

The full verbose output is shown below:

Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/arduino-builder -dump-prefs -logger=machine -hardware /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware -tools /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/tools-builder -tools /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -built-in-libraries /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries -libraries /home/tsmart/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10813 -build-path /tmp/arduino_build_49149 -warnings=none -build-cache /tmp/arduino_cache_198035 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -verbose /home/tsmart/Desktop/code/Arduino/mWebSocketServer/mWebSocketServer.ino
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/arduino-builder -compile -logger=machine -hardware /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware -tools /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/tools-builder -tools /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -built-in-libraries /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries -libraries /home/tsmart/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10813 -build-path /tmp/arduino_build_49149 -warnings=none -build-cache /tmp/arduino_cache_198035 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr -verbose /home/tsmart/Desktop/code/Arduino/mWebSocketServer/mWebSocketServer.ino
Using board 'uno' from platform in folder: /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr
Using core 'arduino' from platform in folder: /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr
Detecting libraries used...
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for WebSocketServer.h: [[email protected]]
ResolveLibrary(WebSocketServer.h)
  -> candidates: [[email protected]]
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for Ethernet.h: [[email protected] [email protected]]
ResolveLibrary(Ethernet.h)
  -> candidates: [[email protected] [email protected]]
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/CryptoLegacy/BlockCipher.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/CryptoLegacy/Cipher.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/CryptoLegacy/Crypto.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/CryptoLegacy/Hash.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/CryptoLegacy/SHA1.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/WebSocket.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/WebSocketClient.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/WebSocketServer.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/base64/Base64.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Arduino/libraries/mWebSockets/src/utility.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/Dhcp.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Alternatives for SPI.h: [[email protected]]
ResolveLibrary(SPI.h)
  -> candidates: [[email protected]]
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/Dhcp.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/Dns.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/Ethernet.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/EthernetClient.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/EthernetServer.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/EthernetUdp.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/socket.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src/utility/w5100.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src/SPI.cpp -o /dev/null -DARDUINO_LIB_DISCOVERY_PHASE
Generating function prototypes...
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp -o /tmp/arduino_build_49149/preproc/ctags_target_for_gcc_minus_e.cpp -DARDUINO_LIB_DISCOVERY_PHASE
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /tmp/arduino_build_49149/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/cores/arduino -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/variants/standard -I/home/tsmart/Arduino/libraries/mWebSockets/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet/src -I/home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI/src /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp -o /tmp/arduino_build_49149/sketch/mWebSocketServer.ino.cpp.o
/home/tsmart/Desktop/code/Arduino/mWebSocketServer/mWebSocketServer.ino: In lambda function:
mWebSocketServer:61:30: error: 'class net::WebSocket' has no member named 'getProtocol'
     const auto protocol = ws.getProtocol();
                              ^~~~~~~~~~~
Multiple libraries were found for "Ethernet.h"
 Used: /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet
 Not used: /home/tsmart/Arduino/libraries/UIPEthernet
Using library mWebSockets at version 1.4.0 in folder: /home/tsmart/Arduino/libraries/mWebSockets 
Using library Ethernet at version 2.0.0 in folder: /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/libraries/Ethernet 
Using library SPI at version 1.0 in folder: /home/tsmart/Desktop/code/Arduino/arduino-1.8.13/hardware/arduino/avr/libraries/SPI 
exit status 1
'class net::WebSocket' has no member named 'getProtocol'

I wish to upload this sketch to an Arduino Uno (ATmega328) with a W5500 Ethernet Shield. How do I fix this issue?
Thanks in advance.

Unreliable connection setup

Describe the bug

If I try to connect from a client to a websocket server implemented with mWebSockets the connection is not always setup.

Environment info

  • IDE w/version: Arduino IDE 1.8.15
  • Platform/Board: Arduino Due
  • Network controller (shield or module): EthernetShield 2

Expected behavior

The connection setup is executed properly every time I try to connect.

Failure log

No failure log output in case of connection is not setup (#define _DEBUG, #define _DUMP_HANDSHAKE, #define _DUMP_HEADER and #define _DUMP_FRAME_DATA are all set).

Log in case connection is setup:

[Line #0] GET / HTTP/1.1
[Line #1] Host: 192.168.1.2
[Line #2] User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
[Line #3] Accept: */*
[Line #4] Accept-Language: de,en-US;q=0.7,en;q=0.3
[Line #5] Accept-Encoding: gzip, deflate
[Line #6] Sec-WebSocket-Version: 13
[Line #7] Origin: moz-extension://d4825527-04cb-4cc5-9a5a-cca3f570223a
[Line #8] Sec-WebSocket-Extensions: permessage-deflate
[Line #9] Sec-WebSocket-Key: On6QMBBNL3JfSru3nICLsg==
[Line #10] Connection: keep-alive, Upgrade
[Line #11] Pragma: no-cache
[Line #12] Cache-Control: no-cache
[Line #13] Upgrade: websocket
[Line #14]

Additional context

Firecamp log output in case connection is not setup:

grafik

Firecamp log output in case connection is setup:

grafik

WiFiEsp(AT) support

Hi,

I just want to start the discussion about using your library with WiFiEspAT. I think that's the simplest way of using it for new fellows in the arduino world like me. None of the websocket libraries have compatibility with WiFiEsp or WiFiEspAT, I think that would be a big plus.

After somedays of learning arduino/C/mWebSocket /WiFiEspAT I was able to make it work. So it is definitely possible. The problem is that it is very unstable and it doesn't seems to be related to the communication with the ESP8266.

Depending on where and how many printf() I had in the code, the behavior changed. And it is always in the mWebSocket side. In one of those case in the WebSocket.cpp code:

if (header.length + offset >= kBufferMaxSize)
      return close(CloseCode::MESSAGE_TOO_BIG, true);

That was returning true for header.length = 5, offset = 0 and kBufferMaxSize = 256. Sometimes the arduino was simply halting in the middle of the code. But like I said, sometimes it works. I don't have any other board to test, but every other sketch works fine and consistently.

Anyhow, an interface with AT commands is something that you would be willing to support and do you have any idea what would be cause of those random behaviors?

Server running at 0.0.0.0:3000

Hello,
I'am using Ethernet Shield (5100) + Arduino Uno
I have followed the procedure, but the debug console is still raiming the same

Initializing ...
Server running at 0.0.0.0:3000

Let me know how to debug this issue, I took to much time to figure out but I can't solve it.
Thanks

Please find my attached code based on simple server

#include <WebSocketServer.h>
#include <Ethernet.h>
using namespace net;

#define _SERIAL Serial
#define PinForEthernet 10
#define _DEBUG
#define _DUMP_HANDSHAKE
#define _DUMP_FRAME_DATA
#define _DUMP_HEADER
#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00



#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
constexpr char kSSID[]{ "SKYNET" };
constexpr char kPassword[]{ "***" };
#else
byte mac[]{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 160);
#endif

constexpr uint16_t port = 3000;
WebSocketServer wss(port);

void setup() {
  
  _SERIAL.begin(9600);
  while (!_SERIAL)
    ;



#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
  //_SERIAL.setDebugOutput(true);
  _SERIAL.printf("\nConnecting to %s ", kSSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(kSSID, kPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    _SERIAL.print(F("."));
  }

  _SERIAL.println(F(" connected"));

  WiFi.printDiag(_SERIAL);

  _SERIAL.print(F("Device IP: "));
  _SERIAL.println(WiFi.localIP());
#else
  _SERIAL.println(F("Initializing ... "));

#if NETWORK_CONTROLLER == ETHERNET_CONTROLLER_W5X00
   Ethernet.init(53);
#endif

  Ethernet.begin(mac, ip);

  _SERIAL.print(F("Server running at "));
  _SERIAL.print(Ethernet.localIP());
  _SERIAL.print(F(":"));
  _SERIAL.println(port);
#endif

  wss.onConnection([](WebSocket &ws) {
    ws.onMessage([](WebSocket &ws, const WebSocket::DataType &dataType,
                   const char *message, uint16_t length) {
      switch (dataType) {
      case WebSocket::DataType::TEXT:
        _SERIAL.print(F("Received: "));
        _SERIAL.println(message);
        break;
      case WebSocket::DataType::BINARY:
        _SERIAL.println(F("Received binary data"));
        break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose(
      [](WebSocket &ws, const WebSocket::CloseCode &code, const char *reason,
        uint16_t length) { _SERIAL.println(F("Disconnected")); });

    _SERIAL.print(F("New client: "));
    _SERIAL.println(ws.getRemoteIP());

    const char message[]{ "Hello from Arduino server!" };
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  wss.begin();
}

uint32_t previousTime = 0;

void loop() { wss.listen(); }

Base64 library

Currently I'm looking into this library for a project of mine (part of #19) and I've noticed that this library requires a base64 implementation, but none of the ones I've been looking at in the Arduino Library Manager actually define the needed functions.

Which library do you need installed to have these base64 functions around? Would you be willed to migrate to a different library, if the library can not be found in the library manager?

Currently I have the following one installed: https://github.com/agdl/Base64

And the following two seem sane from a quick view:

websocket.listen() blocking loop()

Good evening,

I am trying to use your library to connect my ESP32 and a W5500 to my server which is running a node.js script to receive sensor data. The connection is established successfully, however the listen() function is taking up a lot of time in my main.

void Setup() {

....

Ethernet.begin(macaddress);

webSocket.onOpen(WSonOpen);
webSocket.onClose(WSonClose);
webSocket.onMessage(WSonMessage);
webSocket.open(ws_server, ws_port);

....

}

void loop() {
 ...

  Serial.printf("Before listen - %lu\n", millis());
  webSocket.listen();
  //printTime();
  Serial.printf("After listen - %lu\n", millis());

....

}

From my Serial output, my loop is being blocked for 5 Seconds.

Before listen - 391795
After listen - 396795
Reading...
Before listen - 396847
After listen - 401847
Reading...
Before listen - 401899
After listen - 406692

Is there anything I am missing, or do you have any other idea what may be causing it to take so long? I only found #10, but unfortunately, there was no resolution to that problem.

Best regards.

The used network controller should be configurable from the sketch

The approach with selecting the network controller inside the library's config.h is hardly usable in real projects - it is impossible to tweak it for every build.

There are several approaches which can address this issue:

  1. Wrap #define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00 with #ifnded NETWORK_CONTROLLER and #endif so if the build system support global defines, the project will choose the proper network controller.
  2. Do a meaningful guess of the network controller (e.g., when ESP8266 or ESP32 is defined, the chances are high that WiFi is used), so for rigid build systems (like the one in Arduino IDE) the library can be used as is.

Environment info

  • IDE w/version: Arduino IDE 1.8.16
  • Platform/Board: esp8266
  • Network controller (shield or module): WiFi

RSV1 set to one but must be zero

I'm currently in the works of making this library work with MKR1000 and WiFi101 and I'm testing this with a Node.js websocket client. However whenever I try to send a message from Node.js, the connection will fail with Invalid WebSocket frame: RSV1 must be clear, which indicates this library sets RSV1 to one, even though no extension was actually negated (websockets/ws#1140 (comment), https://tools.ietf.org/html/rfc6455#section-5.2).

In my config.h I've uncommented the "debug macros"

#define _DEBUG
#define _DUMP_HANDSHAKE
#define _DUMP_HEADER
#define _DUMP_FRAME_DATA

And on the serial I can see the following getting printed (and that's all of it):

17:43:13.645 -> [Line #0] GET / HTTP/1.1
17:43:13.645 -> [Line #1] Sec-WebSocket-Version: 13
17:43:13.645 -> [Line #2] Sec-WebSocket-Key: aaab5frEyNghA1Yrsz9Fxg==
17:43:13.645 -> [Line #3] Connection: Upgrade
17:43:13.645 -> [Line #4] Upgrade: websocket
17:43:13.645 -> [Line #5] Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
17:43:13.645 -> [Line #6] Host: 192.168.1.39:3000
17:43:13.645 -> [Line #7] 
17:43:13.679 -> New websocket connection

Node.js output:

connected
RangeError: Invalid WebSocket frame: RSV1 must be clear
    at Receiver.getInfo (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:178:14)
    at Receiver.startLoop (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:131:22)
    at Receiver._write (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:78:10)
    at writeOrBuffer (_stream_writable.js:352:12)
    at Receiver.Writable.write (_stream_writable.js:303:10)
    at Socket.socketOnData (C:\Users\GG\Downloads\node_modules\ws\lib\websocket.js:872:35)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:307:12)
    at readableAddChunk (_stream_readable.js:282:9)
    at Socket.Readable.push (_stream_readable.js:221:10) {
  [Symbol(status-code)]: 1002
}

Node.js client code:

const WebSocket = require('ws');

const ws = new WebSocket('ws://192.168.1.39:3000');

const data = {
    "type": "standard",
    "id": 128,
    "dlc": null,
    "rtr": false,
    "data": "hello123"
};

ws.on('error', function (error) {
  console.log(error);
});

ws.on('open', function () {
  console.log('connected');
  setTimeout(() => ws.send(JSON.stringify(data)), 2000);
});

ws.on('message', function (data) {
  console.log(data);
});

I'm using a little more code for all my setup and peripheries, but this is a simplified version:

net::WebSocketServer wss(3000);

void ws_configure_websocket() {
  wss.onConnection([](net::WebSocket& ws) {
    ws.onClose([](net::WebSocket& wsc, const net::WebSocket::CloseCode& code, const char* reason, uint16_t length) {
      Serial.println("Websocket client closed");
    });
    
    ws.onMessage([](net::WebSocket& wsc, const net::WebSocket::DataType& dataType, const char* message, uint16_t length) {
      Serial.println("New websocket message");
    });
    
    Serial.println("New websocket connection");
  });

  wss.begin();
}

void ws_loop_websocket() {
  int status = WiFi.status();

  if (status == WL_CONNECTED) {
    wss.listen();
  }
}

void setup() {
 ws_configure_websocket();
}

void loop() {
  ws_loop_websocket();
}

Serial monitor freezes after "Initializing..."

I get these errors when compiling:

In file included from C:\Users\Aron\Downloads\ArduinoWebSockets-master\examples\simple-server\simple-server.ino:6:0:

C:\Users\Aron\Documents\Arduino\libraries\src/WebSocketClient.h:11:66: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

  bool open(const char *host, uint16_t port = 3000, char path[] = "/");

                                                                  ^

In file included from C:\Users\Aron\Documents\Arduino\libraries\src\WebSocketClient.cpp:1:0:

C:\Users\Aron\Documents\Arduino\libraries\src\WebSocketClient.h:11:66: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

  bool open(const char *host, uint16_t port = 3000, char path[] = "/");

                                                                  ^

C:\Users\Aron\Documents\Arduino\libraries\src\WebSocket.cpp: In member function 'void WebSocket::close(eWebSocketCloseEvent, const char*, uint16_t, bool)':

C:\Users\Aron\Documents\Arduino\libraries\src\WebSocket.cpp:51:15: warning: narrowing conversion of '(int)(((unsigned int)code) >> 8)' from 'int' to 'char' inside { } [-Wnarrowing]

   (code >> 8) & 0xFF,

               ^

C:\Users\Aron\Documents\Arduino\libraries\src\WebSocket.cpp:52:8: warning: narrowing conversion of '(((int)code) & 255)' from 'int' to 'char' inside { } [-Wnarrowing]

   code & 0xFF,

        ^

I'm using arduino uno & W5500 ethernet shield.
I also followed the Requirements and the Installation.
When I open the serial monitor it displays Initializing... but nothing happens after that no matter how much I wait.
Can you please help me ?
Thank you,
Aaron

Websocket disconnect

I am using the websocket client on SAMD21 with a python script as websocket server on pc. What happens if the websocket is stopped or disconnected from a server side? How does the code handle this? Does the code handle this with an error? onClose is not triggered when I disconnect on server side - is this normal?

I am running on SAMD21 with W5500.

WSS connection

Hello, your library is amazing!
I use it with an internet sheild w5500 and an arduino mega and it goes great

My problem:
I haven't found a way to connect to websocket via ssl
for example I would like to connect to:
wss: //echo.websocket.org
how can I do?

thank you

can't send from server Payload > 2048

Describe the bug

On my MwebSockets server i can't send payload > 2048
On varios javascript client i have the error

WebSocketClient.html:37 WebSocket connection to 'ws://192.168.4.30:3000/' failed: Could not decode a text frame as UTF-8.

Environment info

  • IDE w/version [platform.io vs code]
  • Platform/Board: [ESP32]
  • Network controller (shield or module): [W5500 or wifi]

Expected behavior
If my payload is <= 2048 the client receive the message

Failure log

[Line #0] GET / HTTP/1.1
[Line #1] Host: 192.168.4.30:3000
[Line #2] Connection: Upgrade
[Line #3] Pragma: no-cache
[Line #4] Cache-Control: no-cache
[Line #5] User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
[Line #6] Upgrade: websocket
[Line #7] Origin: null
[Line #8] Sec-WebSocket-Version: 13
[Line #9] Accept-Encoding: gzip, deflate
[Line #10] Accept-Language: it,en-GB;q=0.9,en;q=0.8,it-IT;q=0.7
[Line #11] Sec-WebSocket-Key: bEXwqjPKVFCpFdrTY2doLA==
[Line #12] Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
[Line #13]
New client: 192.168.5.25
TX FRAME : OPCODE=1, FIN=True, RSV=0, PAYLOAD-LEN=2049, MASK=None
{"name":"xxxxxxxx","network":"ethernet","wifi_sid":"iot","wifi_password":"wifipwd","softap_password":"12345678","dhcp":0,"ip":"192.168.4.30","subnet":"255.255.255.0","gateway":"192.168.5.1","dns":"192.168.5.4","mqtt":0,"mqtt_ip":"192.168.1.35","mqtt_user"TX BYTES = 2053

Additional context

i have on the config.h

constexpr uint16_t kBufferMaxSize{4096};

w5500 and esp32 websocket server

dear sir,

I was generic esp32 working with ethernet.h ans spi config

i want to implement websocket server to w5500 with esp32

do you have some idear?

thank a lot

Unable to ping IP of Arduino Uno (ATmega328) w/ W5500 after uploading simple-server.ino

I have been able to successfully compile and upload simple-server.ino to my ATmega328 board with a W5500 Ethernet Shield, but I have noticed a few issues with it. Firstly, If I open the Serial Monitor, I obtain something like

14:28:02.662 -> ⸮x⸮⸮⸮

Secondly, when I try and ping the IP Address via a Terminal using an Ethernet connection connected to the same subnet as the Arduino, I cannot successfully ping it:

PING 198.162.1.177 (198.162.1.177) 56(84) bytes of data.
From 198.162.1.21 icmp_seq=1 Destination Host Unreachable
From 198.162.1.21 icmp_seq=2 Destination Host Unreachable
From 198.162.1.21 icmp_seq=3 Destination Host Unreachable

What could be causing these errors? For reference, here is the example I uploaded:

#include <WebSocketServer.h>
using namespace net;

#if PLATFORM_ARCH == PLATFORM_ARCHITECTURE_SAMD21
#  define _SERIAL SerialUSB
#else
#  define _SERIAL Serial
#endif

#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
constexpr char kSSID[]{"SKYNET"};
constexpr char kPassword[]{"***"};
#else
byte mac[]{0xA8, 0x61, 0x0A, 0xAE, 0x69, 0x13};
IPAddress ip(198, 162, 1, 177);

#endif

constexpr uint16_t port = 3000;
WebSocketServer wss{port};

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

#if NETWORK_CONTROLLER == NETWORK_CONTROLLER_WIFI
  //_SERIAL.setDebugOutput(true);
  _SERIAL.printf("\nConnecting to %s ", kSSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(kSSID, kPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    _SERIAL.print(F("."));
  }

  _SERIAL.println(F(" connected"));

  WiFi.printDiag(_SERIAL);

  _SERIAL.print(F("Device IP: "));
  _SERIAL.println(WiFi.localIP());
#else
  _SERIAL.println(F("Initializing ... "));

  // Ethernet.init(10);
  Ethernet.init(53); // Mega2560
  // Ethernet.init(5); // ESPDUINO-32
  // Ethernet.init(PA4); // STM32

  Ethernet.begin(mac, ip);

  _SERIAL.print(F("Server running at "));
  _SERIAL.print(Ethernet.localIP());
  _SERIAL.print(F(":"));
  _SERIAL.println(port);
#endif

  wss.onConnection([](WebSocket &ws) {
    const auto protocol = ws.getProtocol();
    if (protocol) {
      _SERIAL.print(F("Client protocol: "));
      _SERIAL.println(protocol);
    }

    ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                   const char *message, uint16_t length) {
      switch (dataType) {
      case WebSocket::DataType::TEXT:
        _SERIAL.print(F("Received: "));
        _SERIAL.println(message);
        break;
      case WebSocket::DataType::BINARY:
        _SERIAL.println(F("Received binary data"));
        break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
                 uint16_t) { _SERIAL.println(F("Disconnected")); });

    _SERIAL.print(F("New client: "));
    _SERIAL.println(ws.getRemoteIP());

    const char message[]{"Hello from Arduino server!"};
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  wss.begin();
}

void loop() { wss.listen(); }

'SerialUSB' was not declared in this scope

Describe the bug
Compile fails

Using the unmodified "simple-server" example

Environment info

  • IDE w/version: Arduino 1.8.15
  • Platform/Board: Adafruit Feather M4 Express (SAMD51)
  • Network controller (shield or module):
  • mWebSockets Version: 1.5.1

Expected behavior
SAMD51 should be detected correctly

Failure log

/home/laudix/Arduino/libraries/mWebSockets/src/utility.cpp: In function 'void printf(const __FlashStringHelper*, ...)':
/home/laudix/Arduino/libraries/mWebSockets/src/utility.cpp:20:3: error: 'SerialUSB' was not declared in this scope
   SerialUSB.print(buffer);
   ^~~~~~~~~
/home/laudix/Arduino/libraries/mWebSockets/src/utility.cpp:20:3: note: suggested alternative: 'Serial'
   SerialUSB.print(buffer);
   ^~~~~~~~~
   Serial
Multiple libraries were found for "Ethernet.h"
 Used: /opt/arduino-1.8.15/libraries/Ethernet
 Not used: /home/laudix/Arduino/libraries/UIPEthernet
Multiple libraries were found for "Adafruit_ZeroDMA.h"
 Used: /home/laudix/.arduino15/packages/adafruit/hardware/samd/1.7.5/libraries/Adafruit_ZeroDMA
 Not used: /home/laudix/Arduino/libraries/Adafruit_Zero_DMA_Library
exit status 1
Error compiling for board Adafruit Feather M4 Express (SAMD51).

Additional context
editing platform.h (as suggested) didn't repair so reverted back

Get _debugOutput on serial

Hi, thanks for your work on this lib.

I want to debug a failed websocket connection, how can i get _debugOuput calls (in WebSocketClient.cpp for example) to print on serial ?

Wrong value in WebSocketServer.cpp cause a stack overflow error

Hi
I'm currently works whith VSode & PlatformIo
I use this line lib_deps = skaarj1989/mWebSockets @ ^1.4.0 to install mWebSockets libray
my code compil perfect but i have somme trouble in execution when the client connects.

in WebSocketServer.cpp


void WebSocketServer::_acceptRequest(NetClient &client, const char *secKey) {
  char acceptKey[28]{};
  encodeSecKey(acceptKey, secKey);

  char secWebSocketAccept[50]{};
  strcpy_P(secWebSocketAccept, (PGM_P)F("Sec-WebSocket-Accept: "));
  strcat(secWebSocketAccept, acceptKey);

  client.println(F("HTTP/1.1 101 Switching Protocols"));
  //client.println(F("Server: Arduino"));
  //client.println(F("X-Powered-By: mWebSockets"));
  client.println(F("Upgrade: websocket"));
  client.println(F("Connection: Upgrade"));
  client.println(secWebSocketAccept);
  client.println();
}

cause a stack overflow error

I found a solution

char acceptKey[28]{}; muste to be char acceptKey[29]{};
and
char secWebSocketAccept[50]{}; muste to be char secWebSocketAccept[51]{}

// 22 characters for header + 28 for accept key + 1 for NULL

it's same value of 1.33 library
best regard

server closes the websocket after 5 seconds

HI,
I am using the simple server example from your repo for STM32 architecture and W5500 module combined with the stock Ethernet library.
I have the problem that 5 seconds after I start the client application (Firefox on my PC) the client reports that the websocket is closed by the server (this example).

Digging into the code I arrived to WebSocketServer.cpp:

EthernetClient client = m_server.available();
if (client && client.available()) {
WebSocket *ws{ _getWebSocket(client) };
if (!ws) {
const auto end = &m_sockets[kMaxConnections];
for (auto it = &m_sockets[0]; it != end; ++it) {
if (!(*it)) {
if (_handleRequest(client)) {
*it = new WebSocket(client);
ws = *it;
if (_onConnection) _onConnection(*ws);
}
break;
}
}
// Server is full ...
if (!ws) _rejectRequest(client, WebSocketError::SERVICE_UNAVAILABLE);
}
if (ws) ws->_readFrame();

In particular, it seems that line 91 should be only called in the else case of line 74 condition. Otherwise, as it currently is, for the first time when ws is NULL, in line 74, ws will be non-null in line 80 but there are no available data to read, so that the websocket _read() function (see here) called by _readFrame in line 91 will timeout exactly after 5 seconds.

Changing the above mentioned code line in the following way solves the problem:

    if (!ws) {
      const auto end = &m_sockets[kMaxConnections];
      for (auto it = &m_sockets[0]; it != end; ++it) {
        if (!(*it)) {
          if (_handleRequest(client)) {
            *it = new WebSocket(client);
            ws = *it;
            if (_onConnection) _onConnection(*ws);
          }
          break;
        }
      }

      // Server is full ...
      if (!ws) _rejectRequest(client, WebSocketError::SERVICE_UNAVAILABLE);
    } else {
      ws->_readFrame(); // no need to check (ws) again, in line 74 was already checked to be non-null
    }

Please let me know if this change makes sense, at least for me it works.

Support for Portenta H7

Describe the feature

Higher end devices like the Portenta H7 do not provide pgmspace.h. This leads to a compilation error when trying to build code which uses mWebSockets on such a device (file not found error). One way to solve this issue is to provide a pgmspace.h file on the device driver side (more info about this here: arduino/ArduinoCore-mbed#343). Another way is to implement device conditional compilation, meaning adding Portenta H7 to here and here.

@skaarj1989 @facchinm I could provide a PR if you are ok with the second alternative how to extend support of the lib. If not one would have to take the first approach instead. It seems like there is no best practice about which approach to prefer over the other in the Arduino ecosystem BTW.

Environment info

n.a.

Expected behavior

Should compile on Portenta H7.

Additional context

n.a.

'strtok_r' was not declared in this scope, 'strcasecmp' was not declared in this scope

Describe the bug

I am having some compilation errors:

'strtok_r' was not declared in this scope
'strcasecmp' was not declared in this scope

Manually including

#include <Arduino.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

to WebSocketClient.cpp and WebSocketServer.cpp didn't find these functions either, so I am not sure where they could be.

Do we need to define any specific -D flags for GCC?

Apparently strcasecmp is not an iso-c function https://c-for-dummies.com/blog/?p=3863


Environment info

  • IDE: Make/GCC
  • Platform/Board: STM32duino
  • Network controller (shield or module): W5500

Expected behavior
Successful compilation

Failure log

system42/libraries/mWebSockets/src/WebSocketClient.cpp: In member function 'bool net::WebSocketClient::_readResponse(const char*)':
system42/libraries/mWebSockets/src/WebSocketClient.cpp:170:24: error: 'strtok_r' was not declared in this scope; did you mean 'strtok'?
  170 |           char *header{strtok_r(rest, ":", &rest)};
      |                        ^~~~~~~~
      |                        strtok
In file included from system42/Arduino_Core_STM32/cores/arduino/WString.h:29,
                 from system42/Arduino_Core_STM32/cores/arduino/Print.h:26,
                 from system42/Arduino_Core_STM32/cores/arduino/Stream.h:26,
                 from system42/Arduino_Core_STM32/cores/arduino/HardwareSerial.h:29,
                 from system42/Arduino_Core_STM32/cores/arduino/WSerial.h:5,
                 from system42/Arduino_Core_STM32/cores/arduino/wiring.h:48,
                 from system42/Arduino_Core_STM32/cores/arduino/Arduino.h:36,
                 from system42/libraries/Ethernet/src/Ethernet.h:51,
                 from system42/libraries/mWebSockets/src/platform.h:49,
                 from system42/libraries/mWebSockets/src/utility.h:3,
                 from system42/libraries/mWebSockets/src/WebSocket.h:5,
                 from system42/libraries/mWebSockets/src/WebSocketClient.h:5,
                 from system42/libraries/mWebSockets/src/WebSocketClient.cpp:1:
system42/Arduino_Core_STM32/cores/arduino/avr/pgmspace.h:56:28: error: 'strcasecmp' was not declared in this scope; did you mean 'strcasecmp_P'?
   56 | #define strcasecmp_P(a, b) strcasecmp((a), (b))
      |                            ^~~~~~~~~~
system42/libraries/mWebSockets/src/WebSocketClient.cpp:176:15: note: in expansion of macro 'strcasecmp_P'
  176 |           if (strcasecmp_P(header, (PGM_P)F("Upgrade")) == 0) {
      |               ^~~~~~~~~~~~
make: *** [Makefile:794: /home/razor/Desktop/system42/__build/system42/libraries/mWebSockets/src/WebSocketClient.o] Error 1
make: *** Waiting for unfinished jobs....
system42/libraries/mWebSockets/src/WebSocketServer.cpp: In member function 'bool net::WebSocketServer::_handleRequest(NetClient&, char*)':
system42/libraries/mWebSockets/src/WebSocketServer.cpp:179:25: error: 'strtok_r' was not declared in this scope; did you mean 'strtok'?
  179 |           auto header = strtok_r(rest, ":", &rest);
      |                         ^~~~~~~~
      |                         strtok
system42/libraries/mWebSockets/src/WebSocketServer.cpp:278:42: error: 'strtok_r' was not declared in this scope; did you mean 'strtok'?
  278 |                                        : strtok_r(protocols, ",", &rest));
      |                                          ^~~~~~~~
      |                                          strtok
system42/libraries/mWebSockets/src/WebSocketServer.cpp: In member function 'bool net::WebSocketServer::_isValidGET(char*)':
system42/libraries/mWebSockets/src/WebSocketServer.cpp:297:22: error: 'strtok_r' was not declared in this scope; did you mean 'strtok'?
  297 |     const auto pch = strtok_r(rest, " ", &rest);
      |                      ^~~~~~~~
      |                      strtok
system42/libraries/mWebSockets/src/WebSocketServer.cpp: In member function 'bool net::WebSocketServer::_isValidConnection(char*)':
system42/libraries/mWebSockets/src/WebSocketServer.cpp:330:18: error: 'strtok_r' was not declared in this scope; did you mean 'strtok'?
  330 |   while ((item = strtok_r(rest, ",", &rest))) {
      |                  ^~~~~~~~
      |                  strtok
make: *** [Makefile:794: /home/razor/Desktop/system42/__build/system42/libraries/mWebSockets/src/WebSocketServer.o] Error 1

Simplify examples how to use callbacks

Hi,
thanks a lot for this awesome lib.
I would like to suggest to simplify the usage of callbacks in the examples to be more readable (for novices like me :)).
I have written an example here in which the callback function construction is separated in 3 parts, and one liner initialization in setup.
I thought you (or someone else) maybe find it useful.
If you do not think that makes sense, just close this issue.

error 1006

I use example of simple client websocket, in localhost works correctly but in my hosting appear error 1006.
The Arduino connect and desconnect after 1 second in Server.

Can you help me?

This is my code:

#include <WebSocketClient.h>
using namespace net;

byte mac[]{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
# define _SERIAL Serial

WebSocketClient client;

void setup() {
  _SERIAL.begin(9600);
  Ethernet.begin(mac); //, ip);

  _SERIAL.print(F("Device IP: "));
  _SERIAL.println(Ethernet.localIP());

  client.onOpen([](WebSocket &ws) {
    _SERIAL.println(F("Connected"));

    constexpr char message[]{ "Hello from Arduino client!" };
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  client.onMessage([](WebSocket &ws, const WebSocket::DataType &dataType,
                     const char *message, uint16_t length) {
    switch (dataType) {
    case WebSocket::DataType::TEXT:
      _SERIAL.println(F("Received text message"));
      _SERIAL.println(message);
      break;
    case WebSocket::DataType::BINARY:
      _SERIAL.println(F("Received binary data"));
      break;
    }

    ws.send(dataType, message, length); // echo back to server
  });

  client.onClose(
    [](WebSocket &ws, const WebSocket::CloseCode &code, const char *reason,
      uint16_t length) { _SERIAL.println(F("Disconnected")); });

  if (!client.open("server.com", 80, "/chat")) {
    _SERIAL.println(F("Connection failed!"));
    while (true)
      ;
  }
}

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

1006

Arduino SAMD unsupported

I was looking for a websockets server library and I found this which said it supports SAMD, however when trying to compile my code for the MKR1000, it errors with "Unsupported platform".

Since it's a SAMD21 Cortex-M0+ MCU, shouldn't it be supported just like the MKR zero?

The macro is called ARDUINO_ARCH_SAMD (https://github.com/arduino/ArduinoCore-samd/blob/020b419fc1dbca49b23b7c0b5e47d50fb2a04485/cores/arduino/Arduino.h#L129).

In file included from C:\Users\GG\Documents\Arduino\libraries\mWebSockets\src\utility.h:3:0,
                 from C:\Users\GG\Documents\Arduino\libraries\mWebSockets\src\utility.cpp:1:
C:\Users\GG\Documents\Arduino\libraries\mWebSockets\src\platform.h:20:4: error: #error "Unsupported platform"
 #  error "Unsupported platform"
    ^~~~~
C:\Users\GG\Documents\Arduino\libraries\mWebSockets\src\utility.cpp:3:10: fatal error: SHA1.h: No such file or directory
 #include "SHA1.h"
          ^~~~~~~~
compilation terminated.
exit status 1
Error compiling for board Arduino MKR1000.

(The second error seems to complain about a missing "SHA1.h" file, which also comes for the MKR Zero, does that mean this library has a dependency on a hashing library? Please add this library to the library.properties, so the dependency can be automatically downloaded).

Arduino UNO net::ERR_CONNECTION_REFUSED

Hello,

i cant connect to server getting this message:
"Error in connection establishment: net::ERR_CONNECTION_REFUSED"
Im using Arduino UNO.

Thanks for any suggestions.

EDIT: It looks like all ports are closed but why?

Using SSL for Server

I can't make it work with Chrome while with Firefox is ok.
The reason is because the WebSocket Server is insecure.
It is possible to implement SSL to the Library?

  • IDE w/version [Visual Studio Code with platoformio]
  • Platform/Board: [ Arduino Mega 2560 ]
  • Network controller (shield or module): [EthernetShield w5100]

W5100 Server not upgrade connection

Hello,
Your library helps me out a lot. However, I can't establish a connection.

Here's what it gives out DEBUG.

And ws.send(message, length); the first parameter is missing...
I used ws.send( {}, message, length);

Server running at 192.168.88.116:88
[Line #0] GET / HTTP/1.1
[Line #1] Upgrade: websocket
[Line #2] Host: 192.168.88.116:88
[Line #3] Origin: http://192.168.88.116:88
[Line #4] Sec-WebSocket-Key: k01QSkOg5LQDtLtmSpDQxA==
[Line #5] Sec-WebSocket-Version: 13
[Line #6] Connection: upgrade
[Line #7]

Large JSON payloads to a websockets client causes arduino to freeze

Thank you for this fantastic project.
I'm running it as a WebSockets client on a Mega 2560 with the W1500 Ethernet Shield.
Having set my buffer size to 4k, and increased the timeout (in config.h), I find that incoming messages with a payload of anything more than about 2000 bytes cause the device to freeze.

(Application: making an OBS Tally-Light, but some OBS scenes send rather long JSON strings if they have a lot of elements in them. Works perfectly with short messages).

Do you have any advice on gracefully handling long incoming messages, even if there's a way of only reading the first portion and scrapping the rest, please?

webSockets CLient example doesn't compile

Hi @skaarj1989

It seems like the example on the main gitpage here is not compiling , do you possibly have a working example for esp8266 ?
Thank you
Den
See below for compile errors:

Arduino: 1.8.5 (Windows 8.1), Board: "Generic ESP8266 Module, 80 MHz, ck, 26 MHz, 40MHz, DOUT, 1M (512K SPIFFS), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

C:\Users\den\Documents\Arduino\websocketClient_skaarj1989_test_01_181229_1\websocketClient_skaarj1989_test_01_181229_1.ino: In function 'void onOpen(WebSocket&)':

websocketClient_skaarj1989_test_01_181229_1:14: error: no matching function for call to 'WebSocket::send(char [27], size_t)'

   ws.send(message, strlen(message));

                                   ^

C:\Users\den\Documents\Arduino\websocketClient_skaarj1989_test_01_181229_1\websocketClient_skaarj1989_test_01_181229_1.ino:14:35: note: candidates are:

In file included from C:\Users\den\Documents\Arduino\websocketClient_skaarj1989_test_01_181229_1\websocketClient_skaarj1989_test_01_181229_1.ino:5:0:

C:\Users\den\Documents\Arduino\libraries\ArduinoWebSockets\src/WebSocket.h:17:7: note: void WebSocket::send(eWebSocketDataType, const char*, uint16_t)

  void send(const eWebSocketDataType dataType, const char *message, uint16_t length);

       ^

C:\Users\den\Documents\Arduino\libraries\ArduinoWebSockets\src/WebSocket.h:17:7: note:   candidate expects 3 arguments, 2 provided

C:\Users\den\Documents\Arduino\libraries\ArduinoWebSockets\src/WebSocket.h:18:7: note: void WebSocket::send(eWebSocketDataType, const char*, uint16_t, bool)

  void send(const eWebSocketDataType dataType, const char *message, uint16_t length, bool mask);

       ^

C:\Users\den\Documents\Arduino\libraries\ArduinoWebSockets\src/WebSocket.h:18:7: note:   candidate expects 4 arguments, 2 provided

C:\Users\den\Documents\Arduino\websocketClient_skaarj1989_test_01_181229_1\websocketClient_skaarj1989_test_01_181229_1.ino: In function 'void setup()':

websocketClient_skaarj1989_test_01_181229_1:26: error: invalid conversion from 'void (*)(WebSocket&, const char*, uint16_t) {aka void (*)(WebSocket&, const char*, short unsigned int)}' to 'void (*)(WebSocket&, eWebSocketDataType, const char*, uint16_t) {aka void (*)(WebSocket&, eWebSocketDataType, const char*, short unsigned int)}' [-fpermissive]

   client.setOnMessageCallback(onMessage);

                                        ^

In file included from C:\Users\den\Documents\Arduino\websocketClient_skaarj1989_test_01_181229_1\websocketClient_skaarj1989_test_01_181229_1.ino:6:0:

C:\Users\den\Documents\Arduino\libraries\ArduinoWebSockets\src/WebSocketClient.h:18:7: error:   initializing argument 1 of 'void WebSocketClient::setOnMessageCallback(void (*)(WebSocket&, eWebSocketDataType, const char*, uint16_t))' [-fpermissive]

  void setOnMessageCallback(onMessageCallback *callback);

       ^

Multiple libraries were found for "Ethernet.h"
 Used: C:\Users\den\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\libraries\Ethernet
 Not used: C:\Users\den\Documents\Arduino\libraries\Ethernet
 Not used: C:\Program Files (x86)\Arduino\libraries\Ethernet
exit status 1
no matching function for call to 'WebSocket::send(char [27], size_t)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Advanced example

@skaarj1989 Thank you for a great library. I had been using another library, but yours compiles faster, works with simultaneous clients, and exposes useful functions (like countClients).

In the spirit of open-source, I am sharing my results so those that follow have yet another reference.

Ping counts need reset on terminate

m_NumPings needs reset on termination, otherwise any time ping causes disconnect, when you reconnect, the first ping will cause it to disconnect again.

void WebSocket::terminate() {

    //m_Client.flush();

    m_Client.stop();
    m_eReadyState = WSRS_CLOSED;
    m_NumPings = 0; // add this here
}

On message type Binary length uses strlen so length is incorrect

When sending binary data to the Websocket Server the:-

🔴

ws.onMessage(WebSocket &ws, WebSocketDataType dataType, const char *message, uint16_t length)

length is ok on char data that is string based (e.g. Hello.txt) but not ok binary based (e.g. mypic.png)

I thought ArrayBuffer can be any 8 bit unsigned binary data?

🔵

Sending to my node.js websocket server it works.
I think the problem is in WebSocket.cpp line 411 e.g.

onMessage_(*this, BINARY, dataBuffer_, strlen(dataBuffer_));
which would get strange lengths on data that would contain byte value 0;

😥

I hope (I/we) can sort this out, as it renders the websocket server to text only!
unless I'm missing something?

Arduino server send data to client

I got the simple-server. ino and the JS chat-client running straight out of the box, no issues, works like a charm.

my Q is, i would like to add a function in the arduino INO where i send sensor data on regular intervals to the client.

something like:

String mydata="long-data-string";
server.send(mydata);

How can i do this the best and easiest way?

Absolute bare minimum for client to work ?

Hi What is the absolute bare minimum of libraries and code the client needs to work on an ESP8266 ?
I saw under the requirements the following were listed :

arduino-base64
CryptoLegacy from arduinolibs, you can grab it from here
Ethernet "2" for W5500
UIPEthernet #1 or #2 (the choice is yours) for ENC28j60

In the simple example is spi.h needed ?
#include <SPI.h>
Thank you

Den

Mega2560 Websocket server. Garbage in the channel TCP.

Hello.

Along with useful data comes some garbage. What could it be?
Some kind of counter inside the library...
If you do not send data, then 0 1 0 1 0 1 .....

payloadString= pult=@
var= pult
val= @1
60
1
60
1
59
1
58
1
57
1
56
1
55
1
54
1
53
1
52
1
51
1
50
1
49
payloadString= pult=@
var= pult
val= @1
48
1
48
1

ESP8266 webSocket client client connection when desired

Hello

This looks like a great library :-)
Is it possible to enable the : client.listen();
only when required for example when wanting to establish a short connection to transfer a small amount of data and once transfer of data is complete then close it/disconnect/stop listening ?

If yes then can the following :

 client.setOnOpenCallback(onOpen);
  client.setOnCloseCallback(onClose);
  client.setOnMessageCallback(onMessage);
  
  client.open("host", 3000);

Also be invoked at the same time instead of at start(){} ?

Thank you

Den

Example simple-server.ino does not compile in Arduino IDE v2

I've installed mWebScokets (v1.4.0) via the Arduino IDE v2 Library Manager and tried to compile the example examples/simple-server/simple-server.ino for Arduino Mega2560. However there is thrown Compilation error: Error: 2 UNKNOWN: exit status 1.

Connection between mWebSockets server and python client using WSS

I am currently trying to connect my mwebsocket server running on an Arduino Uno (ATmega328P) with a W5500 ethernet shield to a asyncio websockets client in python. The code for the Arduino server is shown below:

#include <WebSocketServer.h>
using namespace net;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[]{0xA8, 0x61, 0x0A, 0xAE, 0x69, 0x13};
IPAddress ip(198, 162, 1, 177);
IPAddress gateway(0,0,0,0);
IPAddress DNSserver(0,0,0,0);
IPAddress subnet(255,255,255,0);

constexpr uint16_t port = 80;
WebSocketServer wss{port};

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  
  Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac,ip,DNSserver,gateway,subnet);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  wss.onConnection([](WebSocket & ws) {
    const auto protocol = ws.getProtocol(); 
    if (protocol) {
      Serial.print(F("Client protocol: "));
      Serial.println(protocol);
    }

    ws.onMessage([](WebSocket & ws, const WebSocket::DataType dataType,
    const char *message, uint16_t length) {
      switch (dataType) {
        case WebSocket::DataType::TEXT:
          Serial.print(F("Received: "));
          Serial.println(message);
          break;
        case WebSocket::DataType::BINARY:
          Serial.println(F("Received binary data"));
          break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
    uint16_t) {
      Serial.println(F("Disconnected"));
    });

    Serial.print(F("New client: "));
    Serial.println(ws.getRemoteIP());

    const char message[] {"Hello from Arduino server!"};
    ws.send(WebSocket::DataType::TEXT, message, strlen(message));
  });

  wss.begin();
  Serial.println(Ethernet.localIP());
}

void loop() {
  wss.listen();
}

And the corresponding python code is shown below:

import asyncio
import websockets

async def test():
    async with websockets.connect( "wss://198.162.1.177:80/") as websocket:
        await websocket.send(str(1.001))
        response = await websocket.recv()
        print(response)
        
 
asyncio.get_event_loop().run_until_complete(test()) # run until test() is finished

My aim is to just receive the message "Hello from Arduino server!" every time the client queries the server. Currently, I have an SSL error that keeps appearing whenever I run the python script:

Traceback (most recent call last):
  File "websocketbasictest.py", line 11, in <module>
    asyncio.get_event_loop().run_until_complete(test()) # run until test() is finished
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 488, in run_until_complete
    return future.result()
  File "websocketbasictest.py", line 5, in test
    async with websockets.connect( "wss://198.162.1.177:80/") as websocket:
  File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py", line 604, in __aenter__
    return await self
  File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py", line 622, in __await_impl__
    transport, protocol = await self._create_connection()
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 824, in create_connection
    sock, protocol_factory, ssl, server_hostname)
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 850, in _create_connection_transport
    yield from waiter
  File "/usr/lib64/python3.6/asyncio/sslproto.py", line 505, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "/usr/lib64/python3.6/asyncio/sslproto.py", line 201, in feed_ssldata
    self._sslobj.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:852)

Is there a mismatch between the communications protocol here? Is there something missing that would allow this connection to take place?

note: array types have different bounds

Describe the bug
Hi, I am trying to use this library but I am getting the following message after compiling:

WebSocketServer.h:14:7: note: array types have different bounds
 class WebSocketServer {
       ^

Environment info

  • IDE 1.8.16
  • Arduino Uno
  • WiFi
  • mWebSockets 1.4.0

Should I be worried about it?

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.