forked from Links2004/arduinoWebSockets
Compare commits
69 Commits
2.0.7
...
ESP32_seri
Author | SHA1 | Date | |
---|---|---|---|
32dd01b91b | |||
388683d4cd | |||
38c401b8af | |||
f7a7ab6ab4 | |||
bdee8b9744 | |||
7ddcdc2bd3 | |||
bde97179bf | |||
9ce044e550 | |||
a796079b0c | |||
e8c0d775fb | |||
5636b02b46 | |||
4b33575af1 | |||
486a612693 | |||
ea8e81c6ce | |||
8a187b523b | |||
ac8d806085 | |||
02e0128802 | |||
01e1fdfb50 | |||
d02932ef21 | |||
5bf8b2407e | |||
50d9a8d6e5 | |||
7443f9b1dc | |||
4b04f6fa53 | |||
a67a8dd0e0 | |||
4759a66a62 | |||
48e690a42a | |||
b059d0711c | |||
a09b8c48ee | |||
94eb4b12e5 | |||
2df62558f1 | |||
86074c90ae | |||
d73e3ecc9c | |||
f62aa6478d | |||
d340c89b09 | |||
05f4cfd7bf | |||
46cff38287 | |||
0b35e32b2a | |||
255f40eaa7 | |||
5e1f9b1c26 | |||
30b6deedd2 | |||
0e6e1c76ee | |||
887683fabb | |||
0b10299549 | |||
1d300084e0 | |||
d9e1e97cf6 | |||
642750e232 | |||
a0c714bf10 | |||
c5461d5779 | |||
b87bce4466 | |||
9608c2d210 | |||
4baf4896cc | |||
4fd2e9d993 | |||
fa580a568f | |||
a93a845780 | |||
83a1539e1e | |||
1bd4638621 | |||
f40a390ab1 | |||
b6c27f74cd | |||
c64a082270 | |||
522a67bc1b | |||
29df9c30f7 | |||
4c1c5378cb | |||
dbabc1025b | |||
1d40160d99 | |||
a388676b40 | |||
8c19d7ba48 | |||
4fc80871a6 | |||
c911776860 | |||
adb52b11e9 |
25
.travis.yml
25
.travis.yml
@ -2,28 +2,31 @@ sudo: false
|
||||
language: bash
|
||||
os:
|
||||
- linux
|
||||
env:
|
||||
matrix:
|
||||
- CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.6.5
|
||||
- CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,FlashSize=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5
|
||||
- CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,Debug=Serial1" IDE_VERSION=1.6.5
|
||||
- CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5
|
||||
- CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5
|
||||
|
||||
script:
|
||||
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
|
||||
- sleep 3
|
||||
- export DISPLAY=:1.0
|
||||
- wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz
|
||||
- tar xf arduino-1.6.5-linux64.tar.xz
|
||||
- mv arduino-1.6.5 $HOME/arduino_ide
|
||||
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
||||
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||
- mv arduino-$IDE_VERSION $HOME/arduino_ide
|
||||
- export PATH="$HOME/arduino_ide:$PATH"
|
||||
- which arduino
|
||||
- mkdir -p $HOME/Arduino/libraries
|
||||
- cp -r $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/arduinoWebSockets
|
||||
- cd $HOME/arduino_ide/hardware
|
||||
- mkdir esp8266com
|
||||
- cd esp8266com
|
||||
- git clone https://github.com/esp8266/Arduino.git esp8266
|
||||
- cd esp8266/tools
|
||||
- python get.py
|
||||
- source $TRAVIS_BUILD_DIR/travis/common.sh
|
||||
- arduino --board esp8266com:esp8266:generic --save-prefs
|
||||
- get_core $CPU
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- arduino --board $BOARD --save-prefs
|
||||
- arduino --get-pref sketchbook.path
|
||||
- build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp8266
|
||||
- build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
@ -23,7 +23,8 @@ a WebSocket Server and Client for Arduino based on RFC6455.
|
||||
- wss / SSL is not possible.
|
||||
|
||||
##### Supported Hardware #####
|
||||
- ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino)
|
||||
- ESP8266 [Arduino for ESP8266](https://github.com/esp8266/Arduino/)
|
||||
- ESP32 [Arduino for ESP32](https://github.com/espressif/arduino-esp32)
|
||||
- ESP31B
|
||||
- Particle with STM32 ARM Cortex M3
|
||||
- ATmega328 with Ethernet Shield (ATmega branch)
|
||||
|
110
examples/esp32/WebSocketClient/WebSocketClient.ino
Normal file
110
examples/esp32/WebSocketClient/WebSocketClient.ino
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* WebSocketClient.ino
|
||||
*
|
||||
* Created on: 24.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiMulti.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
|
||||
WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
|
||||
const uint8_t* src = (const uint8_t*) mem;
|
||||
USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
|
||||
for(uint32_t i = 0; i < len; i++) {
|
||||
if(i % cols == 0) {
|
||||
USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
|
||||
}
|
||||
USE_SERIAL.printf("%02X ", *src);
|
||||
src++;
|
||||
}
|
||||
USE_SERIAL.printf("\n");
|
||||
}
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[WSc] Disconnected!\n");
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
||||
|
||||
// send message to server when Connected
|
||||
webSocket.sendTXT("Connected");
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
// send message to server
|
||||
// webSocket.sendTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
case WStype_ERROR:
|
||||
case WStype_FRAGMENT_TEXT_START:
|
||||
case WStype_FRAGMENT_BIN_START:
|
||||
case WStype_FRAGMENT:
|
||||
case WStype_FRAGMENT_FIN:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// server address, port and URL
|
||||
webSocket.begin("192.168.0.123", 81, "/");
|
||||
|
||||
// event handler
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
// use HTTP Basic Authorization this is optional remove if not needed
|
||||
webSocket.setAuthorization("user", "Password");
|
||||
|
||||
// try ever 5000 again if connection has failed
|
||||
webSocket.setReconnectInterval(5000);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -1,25 +1,39 @@
|
||||
/*
|
||||
* WebSocketClient.ino
|
||||
* WebSocketClientSSL.ino
|
||||
*
|
||||
* Created on: 24.05.2015
|
||||
* Created on: 10.12.2015
|
||||
*
|
||||
* note SSL is only possible with the ESP8266
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiMulti.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
|
||||
const uint8_t* src = (const uint8_t*) mem;
|
||||
USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
|
||||
for(uint32_t i = 0; i < len; i++) {
|
||||
if(i % cols == 0) {
|
||||
USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
|
||||
}
|
||||
USE_SERIAL.printf("%02X ", *src);
|
||||
src++;
|
||||
}
|
||||
USE_SERIAL.printf("\n");
|
||||
}
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
|
||||
@ -30,7 +44,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
||||
|
||||
|
||||
// send message to server when Connected
|
||||
webSocket.sendTXT("Connected");
|
||||
}
|
||||
@ -48,6 +62,12 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
case WStype_ERROR:
|
||||
case WStype_FRAGMENT_TEXT_START:
|
||||
case WStype_FRAGMENT_BIN_START:
|
||||
case WStype_FRAGMENT:
|
||||
case WStype_FRAGMENT_FIN:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@ -76,8 +96,7 @@ void setup() {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.begin("192.168.0.123", 81);
|
||||
//webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization
|
||||
webSocket.beginSSL("192.168.0.123", 81);
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
}
|
104
examples/esp32/WebSocketServer/WebSocketServer.ino
Normal file
104
examples/esp32/WebSocketServer/WebSocketServer.ino
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* WebSocketServer.ino
|
||||
*
|
||||
* Created on: 22.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiMulti.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
#include <WebSocketsServer.h>
|
||||
|
||||
WiFiMulti WiFiMulti;
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
|
||||
const uint8_t* src = (const uint8_t*) mem;
|
||||
USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
|
||||
for(uint32_t i = 0; i < len; i++) {
|
||||
if(i % cols == 0) {
|
||||
USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
|
||||
}
|
||||
USE_SERIAL.printf("%02X ", *src);
|
||||
src++;
|
||||
}
|
||||
USE_SERIAL.printf("\n");
|
||||
}
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendTXT(num, "message here");
|
||||
|
||||
// send data to all connected clients
|
||||
// webSocket.broadcastTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendBIN(num, payload, length);
|
||||
break;
|
||||
case WStype_ERROR:
|
||||
case WStype_FRAGMENT_TEXT_START:
|
||||
case WStype_FRAGMENT_BIN_START:
|
||||
case WStype_FRAGMENT:
|
||||
case WStype_FRAGMENT_FIN:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
92
examples/esp8266/WebSocketClient/WebSocketClient.ino
Normal file
92
examples/esp8266/WebSocketClient/WebSocketClient.ino
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* WebSocketClient.ino
|
||||
*
|
||||
* Created on: 24.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[WSc] Disconnected!\n");
|
||||
break;
|
||||
case WStype_CONNECTED: {
|
||||
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
||||
|
||||
// send message to server when Connected
|
||||
webSocket.sendTXT("Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
// send message to server
|
||||
// webSocket.sendTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// server address, port and URL
|
||||
webSocket.begin("192.168.0.123", 81, "/");
|
||||
|
||||
// event handler
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
// use HTTP Basic Authorization this is optional remove if not needed
|
||||
webSocket.setAuthorization("user", "Password");
|
||||
|
||||
// try ever 5000 again if connection has failed
|
||||
webSocket.setReconnectInterval(5000);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
149
examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino
Normal file
149
examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
WebSocketClientStomp.ino
|
||||
|
||||
Example for connecting and maintining a connection with a STOMP websocket connection.
|
||||
In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).
|
||||
|
||||
Created on: 25.09.2017
|
||||
Author: Martin Becker <mgbckr>, Contact: becker@informatik.uni-wuerzburg.de
|
||||
*/
|
||||
|
||||
// PRE
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
// LIBRARIES
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
|
||||
// SETTINGS
|
||||
|
||||
const char* wlan_ssid = "yourssid";
|
||||
const char* wlan_password = "somepassword";
|
||||
|
||||
const char* ws_host = "the.host.net";
|
||||
const int ws_port = 80;
|
||||
|
||||
// URL for STOMP endpoint.
|
||||
// For the default config of Spring's STOMP support, the default URL is "/socketentry/websocket".
|
||||
const char* stompUrl = "/socketentry/websocket"; // don't forget the leading "/" !!!
|
||||
|
||||
|
||||
// VARIABLES
|
||||
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
// FUNCTIONS
|
||||
|
||||
/**
|
||||
* STOMP messages need to be NULL-terminated (i.e., \0 or \u0000).
|
||||
* However, when we send a String or a char[] array without specifying
|
||||
* a length, the size of the message payload is derived by strlen() internally,
|
||||
* thus dropping any NULL values appended to the "msg"-String.
|
||||
*
|
||||
* To solve this, we first convert the String to a NULL terminated char[] array
|
||||
* via "c_str" and set the length of the payload to include the NULL value.
|
||||
*/
|
||||
void sendMessage(String & msg) {
|
||||
webSocket.sendTXT(msg.c_str(), msg.length() + 1);
|
||||
}
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch (type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[WSc] Disconnected!\n");
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
||||
|
||||
String msg = "CONNECT\r\naccept-version:1.1,1.0\r\nheart-beat:10000,10000\r\n\r\n";
|
||||
sendMessage(msg);
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
{
|
||||
// #####################
|
||||
// handle STOMP protocol
|
||||
// #####################
|
||||
|
||||
String text = (char*) payload;
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
if (text.startsWith("CONNECTED")) {
|
||||
|
||||
// subscribe to some channels
|
||||
|
||||
String msg = "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/messages\n\n";
|
||||
sendMessage(msg);
|
||||
delay(1000);
|
||||
|
||||
// and send a message
|
||||
|
||||
msg = "SEND\ndestination:/app/message\n\n{\"user\":\"esp\",\"message\":\"Hello!\"}";
|
||||
sendMessage(msg);
|
||||
delay(1000);
|
||||
|
||||
} else {
|
||||
|
||||
// do something with messages
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
|
||||
// setup serial
|
||||
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
|
||||
|
||||
// connect to WiFi
|
||||
|
||||
USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ...");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(wlan_ssid, wlan_password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
USE_SERIAL.print(".");
|
||||
}
|
||||
USE_SERIAL.println(" success.");
|
||||
USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP());
|
||||
|
||||
|
||||
// connect to websocket
|
||||
webSocket.begin(ws_host, ws_port, stompUrl);
|
||||
webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config
|
||||
// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
WebSocketClientSockJsAndStomp.ino
|
||||
WebSocketClientStompOverSockJs.ino
|
||||
|
||||
Example for connecting and maintining a connection with a SockJS+STOMP websocket connection.
|
||||
In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).
|
||||
In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).
|
||||
|
||||
Created on: 18.07.2017
|
||||
Author: Martin Becker <mgbckr>, Contact: becker@informatik.uni-wuerzburg.de
|
||||
@ -33,7 +33,7 @@ const int ws_port = 80;
|
||||
// base URL for SockJS (websocket) connection
|
||||
// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36):
|
||||
// ws://<ws_host>:<ws_port>/<ws_baseurl>/<3digits>/<randomstring>/websocket
|
||||
// For the default config of Spring's SockJS/STOMP support the default base URL is "/socketentry/".
|
||||
// For the default config of Spring's SockJS/STOMP support, the default base URL is "/socketentry/".
|
||||
const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!!
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
case WStype_TEXT:
|
||||
{
|
||||
// #####################
|
||||
// handle STOMP protocol
|
||||
// handle SockJs+STOMP protocol
|
||||
// #####################
|
||||
|
||||
String text = (char*) payload;
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* WebSocketServerAllFunctionsDemo.ino
|
||||
*
|
||||
* Created on: 10.05.2018
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#define LED_RED 15
|
||||
#define LED_GREEN 12
|
||||
#define LED_BLUE 13
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED: {
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
if(payload[0] == '#') {
|
||||
// we get RGB data
|
||||
|
||||
// decode rgb data
|
||||
uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
|
||||
|
||||
analogWrite(LED_RED, ((rgb >> 16) & 0xFF));
|
||||
analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF));
|
||||
analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
|
||||
digitalWrite(LED_RED, 1);
|
||||
digitalWrite(LED_GREEN, 1);
|
||||
digitalWrite(LED_BLUE, 1);
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// start webSocket server
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
if(MDNS.begin("esp8266")) {
|
||||
USE_SERIAL.println("MDNS responder started");
|
||||
}
|
||||
|
||||
// handle index
|
||||
server.on("/", []() {
|
||||
// send index.html
|
||||
server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error);};connection.onmessage = function (e) { console.log('Server: ', e.data);};function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if(r.length < 2) { r = '0' + r; } if(g.length < 2) { g = '0' + g; } if(b.length < 2) { b = '0' + b; } var rgb = '#'+r+g+b; console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>");
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("ws", "tcp", 81);
|
||||
|
||||
digitalWrite(LED_RED, 0);
|
||||
digitalWrite(LED_GREEN, 0);
|
||||
digitalWrite(LED_BLUE, 0);
|
||||
|
||||
}
|
||||
|
||||
unsigned long last_10sec = 0;
|
||||
unsigned int counter = 0;
|
||||
|
||||
void loop() {
|
||||
unsigned long t = millis();
|
||||
webSocket.loop();
|
||||
server.handleClient();
|
||||
|
||||
if((t - last_10sec) > 10 * 1000) {
|
||||
counter++;
|
||||
bool ping = (counter % 2);
|
||||
int i = webSocket.connectedClients(ping);
|
||||
USE_SERIAL.printf("%d Connected websocket clients ping: %d\n", i, ping);
|
||||
last_10sec = millis();
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
ESP8266WebServer server = ESP8266WebServer(80);
|
||||
ESP8266WebServer server(80);
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
@ -119,4 +119,3 @@ void loop() {
|
||||
webSocket.loop();
|
||||
server.handleClient();
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Links2004/arduinoWebSockets.git"
|
||||
},
|
||||
"version": "2.0.7",
|
||||
"version": "2.1.1",
|
||||
"license": "LGPL-2.1",
|
||||
"export": {
|
||||
"exclude": [
|
||||
@ -21,8 +21,5 @@
|
||||
]
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
"examples": [
|
||||
"examples/*/*.ino"
|
||||
]
|
||||
"platforms": "atmelavr, espressif8266, espressif32"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
name=WebSockets
|
||||
version=2.0.7
|
||||
version=2.1.1
|
||||
author=Markus Sattler
|
||||
maintainer=Markus Sattler
|
||||
maintainer=Markus Sattler
|
||||
sentence=WebSockets for Arduino (Server + Client)
|
||||
paragraph=use 2.x.x for ESP and 1.3 for AVR
|
||||
category=Communication
|
||||
|
@ -38,6 +38,8 @@ extern "C" {
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <Hash.h>
|
||||
#elif defined(ESP32)
|
||||
#include <hwcrypto/sha.h>
|
||||
#else
|
||||
|
||||
extern "C" {
|
||||
@ -46,12 +48,13 @@ extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param client WSclient_t * ptr to the client struct
|
||||
* @param code uint16_t see RFC
|
||||
* @param reason
|
||||
* @param reasonLen
|
||||
* @param reason ptr to the disconnect reason message
|
||||
* @param reasonLen length of the disconnect reason message
|
||||
*/
|
||||
void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * reason, size_t reasonLen) {
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code);
|
||||
@ -72,8 +75,8 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea
|
||||
*
|
||||
* @param client WSclient_t * ptr to the client struct
|
||||
* @param opcode WSopcode_t
|
||||
* @param payload uint8_t *
|
||||
* @param length size_t
|
||||
* @param payload uint8_t * ptr to the payload
|
||||
* @param length size_t length of the payload
|
||||
* @param mask bool add dummy mask to the frame (needed for web browser)
|
||||
* @param fin bool can be used to send data in more then one frame (set fin on the last frame)
|
||||
* @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!)
|
||||
@ -91,7 +94,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send message frame -------\n", client->num);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload);
|
||||
|
||||
if(opcode == WSop_text) {
|
||||
@ -233,24 +236,24 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
|
||||
// header has be added to payload
|
||||
// payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings
|
||||
// offset in payload is calculatetd 14 - headerSize
|
||||
if(client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) {
|
||||
if(write(client, &payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) {
|
||||
ret = false;
|
||||
}
|
||||
} else {
|
||||
// send header
|
||||
if(client->tcp->write(&buffer[0], headerSize) != headerSize) {
|
||||
if(write(client, &buffer[0], headerSize) != headerSize) {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if(payloadPtr && length > 0) {
|
||||
// send payload
|
||||
if(client->tcp->write(&payloadPtr[0], length) != length) {
|
||||
if(write(client, &payloadPtr[0], length) != length) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%uus).\n", client->num, (micros() - start));
|
||||
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%luus).\n", client->num, (micros() - start));
|
||||
|
||||
#ifdef WEBSOCKETS_USE_BIG_MEM
|
||||
if(useInternBuffer && payloadPtr) {
|
||||
@ -268,7 +271,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
|
||||
void WebSockets::headerDone(WSclient_t * client) {
|
||||
client->status = WSC_CONNECTED;
|
||||
client->cWsRXsize = 0;
|
||||
DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done (%uus).\n", client->num);
|
||||
DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done.\n", client->num);
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
client->cHttpLine = "";
|
||||
handleWebsocket(client);
|
||||
@ -437,11 +440,12 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : "");
|
||||
break;
|
||||
case WSop_close: {
|
||||
uint16_t reasonCode = 1000;
|
||||
if(header->payloadLen >= 2) {
|
||||
reasonCode = payload[0] << 8 | payload[1];
|
||||
}
|
||||
|
||||
#ifndef NODEBUG_WEBSOCKETS
|
||||
uint16_t reasonCode = 1000;
|
||||
if(header->payloadLen >= 2) {
|
||||
reasonCode = payload[0] << 8 | payload[1];
|
||||
}
|
||||
#endif
|
||||
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode);
|
||||
if(header->payloadLen > 2) {
|
||||
DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2));
|
||||
@ -483,6 +487,9 @@ String WebSockets::acceptKey(String & clientKey) {
|
||||
uint8_t sha1HashBin[20] = { 0 };
|
||||
#ifdef ESP8266
|
||||
sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
|
||||
#elif defined(ESP32)
|
||||
String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
esp_sha(SHA1, (unsigned char*)data.c_str(), data.length(), &sha1HashBin[0]);
|
||||
#else
|
||||
clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||
SHA1_CTX ctx;
|
||||
@ -541,7 +548,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
||||
#else
|
||||
unsigned long t = millis();
|
||||
size_t len;
|
||||
DEBUG_WEBSOCKETS("[readCb] n: %d t: %d\n", n, t);
|
||||
DEBUG_WEBSOCKETS("[readCb] n: %zu t: %lu\n", n, t);
|
||||
while(n > 0) {
|
||||
if(client->tcp == NULL) {
|
||||
DEBUG_WEBSOCKETS("[readCb] tcp is null!\n");
|
||||
@ -560,7 +567,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
||||
}
|
||||
|
||||
if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
|
||||
DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %d\n", (millis() - t));
|
||||
DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %lu\n", (millis() - t));
|
||||
if(cb) {
|
||||
cb(client, false);
|
||||
}
|
||||
@ -593,3 +600,56 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* write x byte to tcp or get timeout
|
||||
* @param client WSclient_t *
|
||||
* @param out uint8_t * data buffer
|
||||
* @param n size_t byte count
|
||||
* @return bytes send
|
||||
*/
|
||||
size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) {
|
||||
if(out == NULL) return 0;
|
||||
if(client == NULL) return 0;
|
||||
unsigned long t = millis();
|
||||
size_t len = 0;
|
||||
size_t total = 0;
|
||||
DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t);
|
||||
while(n > 0) {
|
||||
if(client->tcp == NULL) {
|
||||
DEBUG_WEBSOCKETS("[write] tcp is null!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!client->tcp->connected()) {
|
||||
DEBUG_WEBSOCKETS("[write] not connected!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) {
|
||||
DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t));
|
||||
break;
|
||||
}
|
||||
|
||||
len = client->tcp->write((const uint8_t*)out, n);
|
||||
if(len) {
|
||||
t = millis();
|
||||
out += len;
|
||||
n -= len;
|
||||
total += len;
|
||||
//DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
|
||||
} else {
|
||||
//DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n);
|
||||
}
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
delay(0);
|
||||
#endif
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t WebSockets::write(WSclient_t * client, const char *out) {
|
||||
if(client == NULL) return 0;
|
||||
if(out == NULL) return 0;
|
||||
return write(client, (uint8_t*)out, strlen(out));
|
||||
}
|
||||
|
@ -30,39 +30,54 @@
|
||||
#define bit(b) (1UL << (b)) // Taken directly from Arduino.h
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
#error Version 2.x.x currently does not support Arduino with AVR since there is no support for std namespace of c++.
|
||||
#error Use Version 1.x.x. (ATmega branch)
|
||||
#else
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NODEBUG_WEBSOCKETS
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
|
||||
#else
|
||||
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DEBUG_WEBSOCKETS
|
||||
#define DEBUG_WEBSOCKETS(...)
|
||||
#define NODEBUG_WEBSOCKETS
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
|
||||
#define WEBSOCKETS_MAX_DATA_SIZE (15*1024)
|
||||
#define WEBSOCKETS_USE_BIG_MEM
|
||||
#define GET_FREE_HEAP ESP.getFreeHeap()
|
||||
// moves all Header strings to Flash (~300 Byte)
|
||||
//#define WEBSOCKETS_SAVE_RAM
|
||||
#else
|
||||
#ifdef STM32_DEVICE
|
||||
|
||||
#elif defined(STM32_DEVICE)
|
||||
|
||||
#define WEBSOCKETS_MAX_DATA_SIZE (15*1024)
|
||||
#define WEBSOCKETS_USE_BIG_MEM
|
||||
#define GET_FREE_HEAP System.freeMemory()
|
||||
|
||||
#else
|
||||
|
||||
//atmega328p has only 2KB ram!
|
||||
#define WEBSOCKETS_MAX_DATA_SIZE (1024)
|
||||
// moves all Header strings to Flash
|
||||
#define WEBSOCKETS_SAVE_RAM
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define WEBSOCKETS_TCP_TIMEOUT (2000)
|
||||
|
||||
@ -70,36 +85,46 @@
|
||||
#define NETWORK_ESP8266 (1)
|
||||
#define NETWORK_W5100 (2)
|
||||
#define NETWORK_ENC28J60 (3)
|
||||
#define NETWORK_ESP32 (4)
|
||||
|
||||
// max size of the WS Message Header
|
||||
#define WEBSOCKETS_MAX_HEADER_SIZE (14)
|
||||
|
||||
#if !defined(WEBSOCKETS_NETWORK_TYPE)
|
||||
#if !defined(WEBSOCKETS_NETWORK_TYPE)
|
||||
// select Network type based
|
||||
#if defined(ESP8266) || defined(ESP31B)
|
||||
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266
|
||||
//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC
|
||||
//#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100
|
||||
|
||||
#elif defined(ESP32)
|
||||
#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32
|
||||
|
||||
#else
|
||||
#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Includes and defined based on Network Type
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
|
||||
// Note:
|
||||
// No SSL/WSS support for client in Async mode
|
||||
// TLS lib need a sync interface!
|
||||
|
||||
#if !defined(ESP8266) && !defined(ESP31B)
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#elif defined(ESP31B)
|
||||
#include <ESP31BWiFi.h>
|
||||
#else
|
||||
#error "network type ESP8266 ASYNC only possible on the ESP mcu!"
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#else
|
||||
#include <ESP31BWiFi.h>
|
||||
#endif
|
||||
#include <ESPAsyncTCP.h>
|
||||
#include <ESPAsyncTCPbuffer.h>
|
||||
#define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer
|
||||
@ -137,6 +162,13 @@
|
||||
#define WEBSOCKETS_NETWORK_CLASS UIPClient
|
||||
#define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer
|
||||
|
||||
#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#define WEBSOCKETS_NETWORK_CLASS WiFiClient
|
||||
#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer
|
||||
|
||||
#else
|
||||
#error "no network type selected!"
|
||||
#endif
|
||||
@ -201,7 +233,7 @@ typedef struct {
|
||||
|
||||
bool isSocketIO; ///< client for socket.io server
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
bool isSSL; ///< run in ssl mode
|
||||
WiFiClientSecure * ssl;
|
||||
#endif
|
||||
@ -247,10 +279,10 @@ class WebSockets {
|
||||
typedef std::function<void(WSclient_t * client, bool ok)> WSreadWaitCb;
|
||||
#endif
|
||||
|
||||
virtual void clientDisconnect(WSclient_t * client);
|
||||
virtual bool clientIsConnected(WSclient_t * client);
|
||||
virtual void clientDisconnect(WSclient_t * client) = 0;
|
||||
virtual bool clientIsConnected(WSclient_t * client) = 0;
|
||||
|
||||
virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
||||
virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0;
|
||||
|
||||
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0);
|
||||
bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false);
|
||||
@ -267,8 +299,13 @@ class WebSockets {
|
||||
String base64_encode(uint8_t * data, size_t length);
|
||||
|
||||
bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb);
|
||||
virtual size_t write(WSclient_t * client, uint8_t *out, size_t n);
|
||||
size_t write(WSclient_t * client, const char *out);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(var) (void)(var)
|
||||
#endif
|
||||
#endif /* WEBSOCKETS_H_ */
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "WebSockets.h"
|
||||
#include "WebSocketsClient.h"
|
||||
|
||||
|
||||
WebSocketsClient::WebSocketsClient() {
|
||||
_cbEvent = NULL;
|
||||
_client.num = 0;
|
||||
@ -42,14 +41,14 @@ WebSocketsClient::~WebSocketsClient() {
|
||||
void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * protocol) {
|
||||
_host = host;
|
||||
_port = port;
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
_fingerprint = "";
|
||||
#endif
|
||||
|
||||
_client.num = 0;
|
||||
_client.status = WSC_NOT_CONNECTED;
|
||||
_client.tcp = NULL;
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
_client.isSSL = false;
|
||||
_client.ssl = NULL;
|
||||
#endif
|
||||
@ -75,13 +74,20 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url,
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
asyncConnect();
|
||||
#endif
|
||||
|
||||
_lastConnectionFail = 0;
|
||||
_reconnectInterval = 500;
|
||||
}
|
||||
|
||||
void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) {
|
||||
begin(host.c_str(), port, url.c_str(), protocol.c_str());
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, const char * protocol) {
|
||||
return begin(host.toString().c_str(), port, url, protocol);
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) {
|
||||
begin(host, port, url, protocol);
|
||||
_client.isSSL = true;
|
||||
@ -102,7 +108,7 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str
|
||||
beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str());
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) {
|
||||
begin(host, port, url, protocol);
|
||||
_client.isSocketIO = true;
|
||||
@ -121,8 +127,12 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url,
|
||||
*/
|
||||
void WebSocketsClient::loop(void) {
|
||||
if(!clientIsConnected(&_client)) {
|
||||
// do not flood the server
|
||||
if((millis() - _lastConnectionFail) < _reconnectInterval) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
if(_client.isSSL) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n");
|
||||
if(_client.ssl) {
|
||||
@ -151,9 +161,11 @@ void WebSocketsClient::loop(void) {
|
||||
|
||||
if(_client.tcp->connect(_host.c_str(), _port)) {
|
||||
connectedCb();
|
||||
_lastConnectionFail = 0;
|
||||
} else {
|
||||
connectFailedCb();
|
||||
delay(10); //some little delay to not flood the server
|
||||
_lastConnectionFail = millis();
|
||||
|
||||
}
|
||||
} else {
|
||||
handleClientData();
|
||||
@ -239,7 +251,6 @@ bool WebSocketsClient::sendPing(String & payload) {
|
||||
return sendPing((uint8_t *) payload.c_str(), payload.length());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* disconnect one client
|
||||
* @param num uint8_t client id
|
||||
@ -260,7 +271,7 @@ void WebSocketsClient::setAuthorization(const char * user, const char * password
|
||||
String auth = user;
|
||||
auth += ":";
|
||||
auth += password;
|
||||
_client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
|
||||
_client.base64Authorization = base64_encode((uint8_t *) auth.c_str(), auth.length());
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,6 +295,15 @@ void WebSocketsClient::setExtraHeaders(const char * extraHeaders) {
|
||||
_client.extraHeaders = extraHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the reconnect Interval
|
||||
* how long to wait after a connection initiate failed
|
||||
* @param time in ms
|
||||
*/
|
||||
void WebSocketsClient::setReconnectInterval(unsigned long time) {
|
||||
_reconnectInterval = time;
|
||||
}
|
||||
|
||||
//#################################################################################
|
||||
//#################################################################################
|
||||
//#################################################################################
|
||||
@ -298,6 +318,8 @@ void WebSocketsClient::setExtraHeaders(const char * extraHeaders) {
|
||||
void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) {
|
||||
WStype_t type = WStype_ERROR;
|
||||
|
||||
UNUSED(client);
|
||||
|
||||
switch(opcode) {
|
||||
case WSop_text:
|
||||
type = fin ? WStype_TEXT : WStype_FRAGMENT_TEXT_START;
|
||||
@ -305,9 +327,14 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u
|
||||
case WSop_binary:
|
||||
type = fin ? WStype_BIN : WStype_FRAGMENT_BIN_START;
|
||||
break;
|
||||
case WSop_continuation:
|
||||
type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT;
|
||||
break;
|
||||
case WSop_continuation:
|
||||
type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT;
|
||||
break;
|
||||
case WSop_close:
|
||||
case WSop_ping:
|
||||
case WSop_pong:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
runCbEvent(type, payload, length);
|
||||
@ -322,7 +349,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
|
||||
|
||||
bool event = false;
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
if(client->isSSL && client->ssl) {
|
||||
if(client->ssl->connected()) {
|
||||
client->ssl->flush();
|
||||
@ -354,7 +381,6 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
|
||||
client->cCode = 0;
|
||||
client->cKey = "";
|
||||
client->cAccept = "";
|
||||
client->cProtocol = "";
|
||||
client->cVersion = 0;
|
||||
client->cIsUpgrade = false;
|
||||
client->cIsWebsocket = false;
|
||||
@ -407,8 +433,7 @@ void WebSocketsClient::handleClientData(void) {
|
||||
int len = _client.tcp->available();
|
||||
if(len > 0) {
|
||||
switch(_client.status) {
|
||||
case WSC_HEADER:
|
||||
{
|
||||
case WSC_HEADER: {
|
||||
String headerLine = _client.tcp->readStringUntil('\n');
|
||||
handleHeader(&_client, &headerLine);
|
||||
}
|
||||
@ -421,20 +446,19 @@ void WebSocketsClient::handleClientData(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
delay(0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* send the WebSocket header to Server
|
||||
* @param client WSclient_t * ptr to the client struct
|
||||
*/
|
||||
void WebSocketsClient::sendHeader(WSclient_t * client) {
|
||||
|
||||
static const char * NEW_LINE = "\r\n";
|
||||
static const char * NEW_LINE = "\r\n";
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n");
|
||||
|
||||
@ -455,67 +479,67 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
|
||||
String url = client->cUrl;
|
||||
|
||||
if(client->isSocketIO) {
|
||||
if(client->cSessionId.length() == 0) {
|
||||
url += WEBSOCKETS_STRING("&transport=polling");
|
||||
ws_header = false;
|
||||
} else {
|
||||
url += WEBSOCKETS_STRING("&transport=websocket&sid=");
|
||||
url += client->cSessionId;
|
||||
}
|
||||
if(client->cSessionId.length() == 0) {
|
||||
url += WEBSOCKETS_STRING("&transport=polling");
|
||||
ws_header = false;
|
||||
} else {
|
||||
url += WEBSOCKETS_STRING("&transport=websocket&sid=");
|
||||
url += client->cSessionId;
|
||||
}
|
||||
}
|
||||
|
||||
handshake = WEBSOCKETS_STRING("GET ");
|
||||
handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n"
|
||||
"Host: ");
|
||||
handshake += _host + ":" + _port + NEW_LINE;
|
||||
handshake = WEBSOCKETS_STRING("GET ");
|
||||
handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n"
|
||||
"Host: ");
|
||||
handshake += _host + ":" + _port + NEW_LINE;
|
||||
|
||||
if(ws_header) {
|
||||
handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"Sec-WebSocket-Key: ");
|
||||
handshake += client->cKey + NEW_LINE;
|
||||
if(ws_header) {
|
||||
handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"Sec-WebSocket-Key: ");
|
||||
handshake += client->cKey + NEW_LINE;
|
||||
|
||||
if(client->cProtocol.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: ");
|
||||
handshake +=client->cProtocol + NEW_LINE;
|
||||
}
|
||||
if(client->cProtocol.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: ");
|
||||
handshake += client->cProtocol + NEW_LINE;
|
||||
}
|
||||
|
||||
if(client->cExtensions.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: ");
|
||||
handshake +=client->cExtensions + NEW_LINE;
|
||||
}
|
||||
} else {
|
||||
handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n");
|
||||
}
|
||||
if(client->cExtensions.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: ");
|
||||
handshake += client->cExtensions + NEW_LINE;
|
||||
}
|
||||
} else {
|
||||
handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n");
|
||||
}
|
||||
|
||||
// add extra headers; by default this includes "Origin: file://"
|
||||
if (client->extraHeaders) {
|
||||
handshake += client->extraHeaders + NEW_LINE;
|
||||
}
|
||||
// add extra headers; by default this includes "Origin: file://"
|
||||
if(client->extraHeaders) {
|
||||
handshake += client->extraHeaders + NEW_LINE;
|
||||
}
|
||||
|
||||
handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n");
|
||||
handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n");
|
||||
|
||||
if(client->base64Authorization.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Authorization: Basic ");
|
||||
handshake += client->base64Authorization + NEW_LINE;
|
||||
}
|
||||
if(client->base64Authorization.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Authorization: Basic ");
|
||||
handshake += client->base64Authorization + NEW_LINE;
|
||||
}
|
||||
|
||||
if(client->plainAuthorization.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Authorization: ");
|
||||
handshake += client->plainAuthorization + NEW_LINE;
|
||||
}
|
||||
if(client->plainAuthorization.length() > 0) {
|
||||
handshake += WEBSOCKETS_STRING("Authorization: ");
|
||||
handshake += client->plainAuthorization + NEW_LINE;
|
||||
}
|
||||
|
||||
handshake += NEW_LINE;
|
||||
handshake += NEW_LINE;
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str());
|
||||
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length());
|
||||
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t* )handshake.c_str());
|
||||
write(client, (uint8_t*) handshake.c_str(), handshake.length());
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
|
||||
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
|
||||
#endif
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start));
|
||||
DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start));
|
||||
|
||||
}
|
||||
|
||||
@ -535,7 +559,12 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
|
||||
} else if(headerLine->indexOf(':')) {
|
||||
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
|
||||
String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
|
||||
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
|
||||
|
||||
// remove space in the beginning (RFC2616)
|
||||
if(headerValue[0] == ' ') {
|
||||
headerValue.remove(0, 1);
|
||||
}
|
||||
|
||||
if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) {
|
||||
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) {
|
||||
@ -555,10 +584,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
|
||||
client->cVersion = headerValue.toInt();
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) {
|
||||
if (headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) {
|
||||
if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) {
|
||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";"));
|
||||
} else {
|
||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
|
||||
} else {
|
||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -604,6 +633,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
ok = false;
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode);
|
||||
clientDisconnect(client);
|
||||
_lastConnectionFail = millis();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -627,19 +657,19 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n");
|
||||
headerDone(client);
|
||||
|
||||
|
||||
runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length());
|
||||
|
||||
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) {
|
||||
sendHeader(client);
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
|
||||
if(clientIsConnected(client)) {
|
||||
client->tcp->write("This is a webSocket client!");
|
||||
}
|
||||
clientDisconnect(client);
|
||||
}
|
||||
}
|
||||
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) {
|
||||
sendHeader(client);
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
|
||||
_lastConnectionFail = millis();
|
||||
if(clientIsConnected(client)) {
|
||||
write(client, "This is a webSocket client!");
|
||||
}
|
||||
clientDisconnect(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebSocketsClient::connectedCb() {
|
||||
@ -648,15 +678,15 @@ void WebSocketsClient::connectedCb() {
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
_client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num);
|
||||
client->status = WSC_NOT_CONNECTED;
|
||||
client->tcp = NULL;
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num);
|
||||
client->status = WSC_NOT_CONNECTED;
|
||||
client->tcp = NULL;
|
||||
|
||||
// reconnect
|
||||
c->asyncConnect();
|
||||
// reconnect
|
||||
c->asyncConnect();
|
||||
|
||||
return true;
|
||||
}, this, std::placeholders::_1, &_client));
|
||||
return true;
|
||||
}, this, std::placeholders::_1, &_client));
|
||||
#endif
|
||||
|
||||
_client.status = WSC_HEADER;
|
||||
@ -683,7 +713,6 @@ void WebSocketsClient::connectedCb() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WebSocketsClient::connectFailedCb() {
|
||||
DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port);
|
||||
}
|
||||
@ -702,26 +731,26 @@ void WebSocketsClient::asyncConnect() {
|
||||
}
|
||||
|
||||
tcpclient->onDisconnect([](void *obj, AsyncClient* c) {
|
||||
c->free();
|
||||
delete c;
|
||||
});
|
||||
c->free();
|
||||
delete c;
|
||||
});
|
||||
|
||||
tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) {
|
||||
ws->_client.tcp = new AsyncTCPbuffer(tcp);
|
||||
if(!ws->_client.tcp) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n");
|
||||
ws->connectFailedCb();
|
||||
return;
|
||||
}
|
||||
ws->connectedCb();
|
||||
}, this, std::placeholders::_2));
|
||||
ws->_client.tcp = new AsyncTCPbuffer(tcp);
|
||||
if(!ws->_client.tcp) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n");
|
||||
ws->connectFailedCb();
|
||||
return;
|
||||
}
|
||||
ws->connectedCb();
|
||||
}, this, std::placeholders::_2));
|
||||
|
||||
tcpclient->onError(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) {
|
||||
ws->connectFailedCb();
|
||||
ws->connectFailedCb();
|
||||
|
||||
// reconnect
|
||||
ws->asyncConnect();
|
||||
}, this, std::placeholders::_2));
|
||||
// reconnect
|
||||
ws->asyncConnect();
|
||||
}, this, std::placeholders::_2));
|
||||
|
||||
if(!tcpclient->connect(_host.c_str(), _port)) {
|
||||
connectFailedCb();
|
||||
|
@ -37,12 +37,13 @@ class WebSocketsClient: private WebSockets {
|
||||
|
||||
|
||||
WebSocketsClient(void);
|
||||
~WebSocketsClient(void);
|
||||
virtual ~WebSocketsClient(void);
|
||||
|
||||
void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
|
||||
void begin(String host, uint16_t port, String url = "/", String protocol = "arduino");
|
||||
void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino");
|
||||
void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino");
|
||||
#endif
|
||||
@ -50,7 +51,7 @@ class WebSocketsClient: private WebSockets {
|
||||
void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
||||
void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
||||
void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||
#endif
|
||||
@ -83,17 +84,22 @@ class WebSocketsClient: private WebSockets {
|
||||
|
||||
void setExtraHeaders(const char * extraHeaders = NULL);
|
||||
|
||||
void setReconnectInterval(unsigned long time);
|
||||
|
||||
protected:
|
||||
String _host;
|
||||
uint16_t _port;
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
String _fingerprint;
|
||||
#endif
|
||||
WSclient_t _client;
|
||||
|
||||
WebSocketClientEvent _cbEvent;
|
||||
|
||||
unsigned long _lastConnectionFail;
|
||||
unsigned long _reconnectInterval;
|
||||
|
||||
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
||||
|
||||
void clientDisconnect(WSclient_t * client);
|
||||
|
@ -29,6 +29,7 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
|
||||
_port = port;
|
||||
_origin = origin;
|
||||
_protocol = protocol;
|
||||
_runnning = false;
|
||||
|
||||
_server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port);
|
||||
|
||||
@ -43,18 +44,14 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
|
||||
_httpHeaderValidationFunc = NULL;
|
||||
_mandatoryHttpHeaders = NULL;
|
||||
_mandatoryHttpHeaderCount = 0;
|
||||
|
||||
memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX));
|
||||
}
|
||||
|
||||
|
||||
WebSocketsServer::~WebSocketsServer() {
|
||||
// disconnect all clients
|
||||
disconnect();
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
_server->close();
|
||||
#else
|
||||
// TODO how to close server?
|
||||
#endif
|
||||
close();
|
||||
|
||||
if (_mandatoryHttpHeaders)
|
||||
delete[] _mandatoryHttpHeaders;
|
||||
@ -75,7 +72,7 @@ void WebSocketsServer::begin(void) {
|
||||
client->num = i;
|
||||
client->status = WSC_NOT_CONNECTED;
|
||||
client->tcp = NULL;
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
client->isSSL = false;
|
||||
client->ssl = NULL;
|
||||
#endif
|
||||
@ -98,23 +95,43 @@ void WebSocketsServer::begin(void) {
|
||||
|
||||
#ifdef ESP8266
|
||||
randomSeed(RANDOM_REG32);
|
||||
#elif defined(ESP32)
|
||||
#define DR_REG_RNG_BASE 0x3ff75144
|
||||
randomSeed(READ_PERI_REG(DR_REG_RNG_BASE));
|
||||
#else
|
||||
// TODO find better seed
|
||||
randomSeed(millis());
|
||||
#endif
|
||||
|
||||
_runnning = true;
|
||||
_server->begin();
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n");
|
||||
}
|
||||
|
||||
void WebSocketsServer::close(void) {
|
||||
_runnning = false;
|
||||
disconnect();
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
_server->close();
|
||||
#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
_server->end();
|
||||
#else
|
||||
// TODO how to close server?
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
/**
|
||||
* called in arduino loop
|
||||
*/
|
||||
void WebSocketsServer::loop(void) {
|
||||
handleNewClients();
|
||||
handleClientData();
|
||||
if(_runnning) {
|
||||
handleNewClients();
|
||||
handleClientData();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -386,7 +403,25 @@ void WebSocketsServer::setAuthorization(const char * auth) {
|
||||
}
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
/**
|
||||
* count the connected clients (optional ping them)
|
||||
* @param ping bool ping the connected clients
|
||||
*/
|
||||
int WebSocketsServer::connectedClients(bool ping) {
|
||||
WSclient_t * client;
|
||||
int count = 0;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
client = &_clients[i];
|
||||
if(client->status == WSC_CONNECTED) {
|
||||
if(ping != true || sendPing(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
/**
|
||||
* get an IP for a client
|
||||
* @param num uint8_t client id
|
||||
@ -423,7 +458,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
|
||||
client->tcp = TCPclient;
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
client->isSSL = false;
|
||||
client->tcp->setNoDelay(true);
|
||||
#endif
|
||||
@ -432,7 +467,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT);
|
||||
#endif
|
||||
client->status = WSC_HEADER;
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
IPAddress ip = client->tcp->remoteIP();
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]);
|
||||
#else
|
||||
@ -483,6 +518,11 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u
|
||||
case WSop_continuation:
|
||||
type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT;
|
||||
break;
|
||||
case WSop_close:
|
||||
case WSop_ping:
|
||||
case WSop_pong:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
runCbEvent(client->num, type, payload, length);
|
||||
@ -496,7 +536,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u
|
||||
void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
||||
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
if(client->isSSL && client->ssl) {
|
||||
if(client->ssl->connected()) {
|
||||
client->ssl->flush();
|
||||
@ -582,12 +622,12 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
|
||||
*/
|
||||
void WebSocketsServer::handleNewClients(void) {
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
while(_server->hasClient()) {
|
||||
#endif
|
||||
bool ok = false;
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
// store new connection
|
||||
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
||||
#else
|
||||
@ -603,7 +643,7 @@ void WebSocketsServer::handleNewClients(void) {
|
||||
|
||||
if(!ok) {
|
||||
// no free space to handle client
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
IPAddress ip = tcpClient->remoteIP();
|
||||
DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
||||
#else
|
||||
@ -612,7 +652,7 @@ void WebSocketsServer::handleNewClients(void) {
|
||||
tcpClient->stop();
|
||||
}
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
delay(0);
|
||||
}
|
||||
#endif
|
||||
@ -677,55 +717,60 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
|
||||
static const char * NEW_LINE = "\r\n";
|
||||
|
||||
headerLine->trim(); // remove \r
|
||||
headerLine->trim(); // remove \r
|
||||
|
||||
if(headerLine->length() > 0) {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str());
|
||||
if(headerLine->length() > 0) {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str());
|
||||
|
||||
// websocket requests always start with GET see rfc6455
|
||||
if(headerLine->startsWith("GET ")) {
|
||||
// websocket requests always start with GET see rfc6455
|
||||
if(headerLine->startsWith("GET ")) {
|
||||
|
||||
// cut URL out
|
||||
client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4));
|
||||
// cut URL out
|
||||
client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4));
|
||||
|
||||
//reset non-websocket http header validation state for this client
|
||||
//reset non-websocket http header validation state for this client
|
||||
client->cHttpHeadersValid = true;
|
||||
client->cMandatoryHeadersCount = 0;
|
||||
|
||||
} else if(headerLine->indexOf(':')) {
|
||||
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
|
||||
String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);
|
||||
} else if(headerLine->indexOf(':')) {
|
||||
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
|
||||
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
|
||||
|
||||
if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) {
|
||||
headerValue.toLowerCase();
|
||||
if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) {
|
||||
client->cIsUpgrade = true;
|
||||
}
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) {
|
||||
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) {
|
||||
client->cIsWebsocket = true;
|
||||
}
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
|
||||
client->cVersion = headerValue.toInt();
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) {
|
||||
client->cKey = headerValue;
|
||||
client->cKey.trim(); // see rfc6455
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) {
|
||||
client->cProtocol = headerValue;
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) {
|
||||
client->cExtensions = headerValue;
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) {
|
||||
client->base64Authorization = headerValue;
|
||||
} else {
|
||||
client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue);
|
||||
if (_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) {
|
||||
client->cMandatoryHeadersCount++;
|
||||
}
|
||||
}
|
||||
// remove space in the beginning (RFC2616)
|
||||
if(headerValue[0] == ' ') {
|
||||
headerValue.remove(0, 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
|
||||
}
|
||||
if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) {
|
||||
headerValue.toLowerCase();
|
||||
if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) {
|
||||
client->cIsUpgrade = true;
|
||||
}
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) {
|
||||
if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) {
|
||||
client->cIsWebsocket = true;
|
||||
}
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
|
||||
client->cVersion = headerValue.toInt();
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) {
|
||||
client->cKey = headerValue;
|
||||
client->cKey.trim(); // see rfc6455
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) {
|
||||
client->cProtocol = headerValue;
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) {
|
||||
client->cExtensions = headerValue;
|
||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) {
|
||||
client->base64Authorization = headerValue;
|
||||
} else {
|
||||
client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue);
|
||||
if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) {
|
||||
client->cMandatoryHeadersCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
|
||||
}
|
||||
|
||||
(*headerLine) = "";
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
@ -747,11 +792,11 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
|
||||
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
|
||||
|
||||
if(ok) {
|
||||
if(client->cUrl.length() == 0) {
|
||||
ok = false;
|
||||
}
|
||||
if(client->cKey.length() == 0) {
|
||||
if(ok) {
|
||||
if(client->cUrl.length() == 0) {
|
||||
ok = false;
|
||||
}
|
||||
if(client->cKey.length() == 0) {
|
||||
ok = false;
|
||||
}
|
||||
if(client->cVersion != 13) {
|
||||
@ -809,7 +854,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str());
|
||||
|
||||
client->tcp->write((uint8_t*)handshake.c_str(), handshake.length());
|
||||
write(client, (uint8_t*)handshake.c_str(), handshake.length());
|
||||
|
||||
headerDone(client);
|
||||
|
||||
|
@ -27,7 +27,9 @@
|
||||
|
||||
#include "WebSockets.h"
|
||||
|
||||
#ifndef WEBSOCKETS_SERVER_CLIENT_MAX
|
||||
#define WEBSOCKETS_SERVER_CLIENT_MAX (5)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -44,9 +46,10 @@ public:
|
||||
#endif
|
||||
|
||||
WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino");
|
||||
~WebSocketsServer(void);
|
||||
virtual ~WebSocketsServer(void);
|
||||
|
||||
void begin(void);
|
||||
void close(void);
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
void loop(void);
|
||||
@ -92,7 +95,9 @@ public:
|
||||
void setAuthorization(const char * user, const char * password);
|
||||
void setAuthorization(const char * auth);
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
int connectedClients(bool ping = false);
|
||||
|
||||
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
IPAddress remoteIP(uint8_t num);
|
||||
#endif
|
||||
|
||||
@ -111,6 +116,8 @@ protected:
|
||||
WebSocketServerEvent _cbEvent;
|
||||
WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc;
|
||||
|
||||
bool _runnning;
|
||||
|
||||
bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
|
||||
|
||||
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
||||
|
@ -9,6 +9,10 @@ For details, see http://sourceforge.net/projects/libb64
|
||||
#include <core_esp8266_features.h>
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#define CORE_HAS_LIBB64
|
||||
#endif
|
||||
|
||||
#ifndef CORE_HAS_LIBB64
|
||||
#include "cdecode_inc.h"
|
||||
|
||||
@ -32,9 +36,9 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex
|
||||
const char* codechar = code_in;
|
||||
char* plainchar = plaintext_out;
|
||||
char fragment;
|
||||
|
||||
|
||||
*plainchar = state_in->plainchar;
|
||||
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
while (1)
|
||||
|
@ -9,6 +9,10 @@ For details, see http://sourceforge.net/projects/libb64
|
||||
#include <core_esp8266_features.h>
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#define CORE_HAS_LIBB64
|
||||
#endif
|
||||
|
||||
#ifndef CORE_HAS_LIBB64
|
||||
#include "cencode_inc.h"
|
||||
|
||||
@ -35,9 +39,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
|
||||
char* codechar = code_out;
|
||||
char result;
|
||||
char fragment;
|
||||
|
||||
|
||||
result = state_in->result;
|
||||
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
while (1)
|
||||
@ -76,7 +80,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x03f) >> 0;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
|
||||
|
||||
++(state_in->stepcount);
|
||||
if (state_in->stepcount == CHARS_PER_LINE/4)
|
||||
{
|
||||
@ -92,7 +96,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
char* codechar = code_out;
|
||||
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
case step_B:
|
||||
@ -108,7 +112,7 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||
break;
|
||||
}
|
||||
*codechar++ = 0x00;
|
||||
|
||||
|
||||
return codechar - code_out;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ A million repetitions of "a"
|
||||
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
|
||||
#ifndef ESP8266
|
||||
#if !defined(ESP8266) && !defined(ESP32)
|
||||
|
||||
#define SHA1HANDSOFF
|
||||
|
||||
|
@ -5,7 +5,7 @@ By Steve Reid <steve@edmweb.com>
|
||||
100% Public Domain
|
||||
*/
|
||||
|
||||
#ifndef ESP8266
|
||||
#if !defined(ESP8266) && !defined(ESP32)
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[5];
|
||||
@ -18,4 +18,4 @@ void SHA1Init(SHA1_CTX* context);
|
||||
void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len);
|
||||
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@ var server = http.createServer(function(request, response) {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
});
|
||||
server.listen(81, function() {
|
||||
server.listen(8011, function() {
|
||||
console.log((new Date()) + ' Server is listening on port 8011');
|
||||
});
|
||||
|
||||
@ -54,4 +54,4 @@ wsServer.on('request', function(request) {
|
||||
});
|
||||
|
||||
connection.sendUTF("Hallo Client!");
|
||||
});
|
||||
});
|
||||
|
@ -16,9 +16,38 @@ function build_sketches()
|
||||
$arduino --verify $sketch;
|
||||
local result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
echo "Build failed ($1)"
|
||||
echo "Build failed ($sketch) build verbose..."
|
||||
$arduino --verify --verbose --preserve-temp-files $sketch
|
||||
result=$?
|
||||
fi
|
||||
if [ $result -ne 0 ]; then
|
||||
echo "Build failed ($1) $sketch"
|
||||
return $result
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
function get_core()
|
||||
{
|
||||
echo Setup core for $1
|
||||
|
||||
cd $HOME/arduino_ide/hardware
|
||||
|
||||
if [ "$1" = "esp8266" ] ; then
|
||||
mkdir esp8266com
|
||||
cd esp8266com
|
||||
git clone https://github.com/esp8266/Arduino.git esp8266
|
||||
cd esp8266/tools
|
||||
python get.py
|
||||
fi
|
||||
|
||||
if [ "$1" = "esp32" ] ; then
|
||||
mkdir espressif
|
||||
cd espressif
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32
|
||||
cd esp32/tools
|
||||
python get.py
|
||||
fi
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user