Simple to use implementation of WebSockets for microcontrollers.
List of supported IDEs:
List of supported MCUs:
WebSocketServer compatible browsers:
The Autobahn|Testsuite reports for server and client
Some tests will never pass just because of memory lack in ATmega family.
Use Arduino Download Manager or follow this guide.
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 };
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 |
#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();
}
// 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;
});
// 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
#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();
}
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
simple-client.ino
example (without debug output, 128 bytes data buffer)
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%) |
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%) |
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%) |
...