mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-06-25 15:01:36 +02:00
Compare commits
47 Commits
2.3.0
...
esp32-ssl-
Author | SHA1 | Date | |
---|---|---|---|
f6e730c2b4 | |||
7c3b1b7408 | |||
738e43fda4 | |||
f55bf8d4ed | |||
a484da47ed | |||
4355199120 | |||
0a4fcd44c2 | |||
3a2b757155 | |||
900d81e534 | |||
0ecef8c552 | |||
410489f7c5 | |||
ec22d67c12 | |||
39e6a8e709 | |||
784b7f9cb8 | |||
fd83d6ad45 | |||
0e729cd896 | |||
2f21590e55 | |||
c98baafda7 | |||
983b9801fb | |||
e70262dab9 | |||
4a05eab627 | |||
822618f606 | |||
1b4f186fa6 | |||
c68e015322 | |||
dc30a2b7bf | |||
6bee53a8bd | |||
ebb87cdc8a | |||
e7ab913693 | |||
52547ec47c | |||
74411bf729 | |||
f0cc36dede | |||
074a674833 | |||
8239e1625e | |||
c5900db636 | |||
9470961d85 | |||
04919f848f | |||
25318111a1 | |||
08caf3bfc6 | |||
fb26433e75 | |||
4f52a0f38e | |||
f20fbbfcd9 | |||
28cd929e7e | |||
826c6b423a | |||
7fea0b8bdf | |||
4db14451fb | |||
80bf087cd0 | |||
5caff59f7f |
188
.github/workflows/main.yml
vendored
Normal file
188
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 5'
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
release:
|
||||||
|
types: [ published, created, edited ]
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
check_version_files:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: check version
|
||||||
|
run: |
|
||||||
|
$GITHUB_WORKSPACE/travis/version.py --check
|
||||||
|
|
||||||
|
prepare_example_json:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: generate examples
|
||||||
|
id: set-matrix
|
||||||
|
run: |
|
||||||
|
source $GITHUB_WORKSPACE/travis/common.sh
|
||||||
|
cd $GITHUB_WORKSPACE
|
||||||
|
echo -en "::set-output name=matrix::"
|
||||||
|
echo -en "["
|
||||||
|
|
||||||
|
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80
|
||||||
|
echo -en ","
|
||||||
|
|
||||||
|
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1
|
||||||
|
echo -en ","
|
||||||
|
|
||||||
|
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.13 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80
|
||||||
|
echo -en ","
|
||||||
|
|
||||||
|
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.13 espressif:esp32:esp32:FlashFreq=80
|
||||||
|
|
||||||
|
echo -en "]"
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||||
|
|
||||||
|
prepare_ide:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
IDE_VERSION: [1.8.13, 1.6.13]
|
||||||
|
env:
|
||||||
|
IDE_VERSION: ${{ matrix.IDE_VERSION }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Get Date
|
||||||
|
id: get-date
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: cache_all
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/home/runner/arduino_ide
|
||||||
|
/home/runner/Arduino
|
||||||
|
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }}
|
||||||
|
|
||||||
|
- name: download IDE
|
||||||
|
if: steps.cache_all.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz -q
|
||||||
|
tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||||
|
mv arduino-$IDE_VERSION $HOME/arduino_ide
|
||||||
|
|
||||||
|
- name: download ArduinoJson
|
||||||
|
if: steps.cache_all.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/Arduino/libraries
|
||||||
|
wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip -q
|
||||||
|
unzip 6.x.zip
|
||||||
|
mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson
|
||||||
|
|
||||||
|
- name: download esp8266
|
||||||
|
if: steps.cache_all.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
source $GITHUB_WORKSPACE/travis/common.sh
|
||||||
|
get_core esp8266
|
||||||
|
|
||||||
|
- name: download esp32
|
||||||
|
if: steps.cache_all.outputs.cache-hit != 'true' && matrix.IDE_VERSION != '1.6.13'
|
||||||
|
run: |
|
||||||
|
source $GITHUB_WORKSPACE/travis/common.sh
|
||||||
|
get_core esp32
|
||||||
|
|
||||||
|
build:
|
||||||
|
needs: [prepare_ide, prepare_example_json]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include: ${{ fromJson(needs.prepare_example_json.outputs.matrix) }}
|
||||||
|
env:
|
||||||
|
CPU: ${{ matrix.cpu }}
|
||||||
|
BOARD: ${{ matrix.board }}
|
||||||
|
IDE_VERSION: ${{ matrix.ideversion }}
|
||||||
|
SKETCH: ${{ matrix.sketch }}
|
||||||
|
|
||||||
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: install libgtk2.0-0
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libgtk2.0-0
|
||||||
|
|
||||||
|
- name: Get Date
|
||||||
|
id: get-date
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: cache_all
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/home/runner/arduino_ide
|
||||||
|
/home/runner/Arduino
|
||||||
|
key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }}
|
||||||
|
|
||||||
|
- name: install python serial
|
||||||
|
if: matrix.cpu == 'esp32'
|
||||||
|
run: |
|
||||||
|
sudo pip3 install pyserial
|
||||||
|
sudo pip install pyserial
|
||||||
|
# sudo apt install python-is-python3
|
||||||
|
|
||||||
|
- name: start DISPLAY
|
||||||
|
run: |
|
||||||
|
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
|
||||||
|
export DISPLAY=:1.0
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
- name: test IDE
|
||||||
|
run: |
|
||||||
|
export PATH="$HOME/arduino_ide:$PATH"
|
||||||
|
which arduino
|
||||||
|
|
||||||
|
- name: copy code
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/Arduino/libraries/
|
||||||
|
cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets
|
||||||
|
|
||||||
|
- name: config IDE
|
||||||
|
run: |
|
||||||
|
export DISPLAY=:1.0
|
||||||
|
export PATH="$HOME/arduino_ide:$PATH"
|
||||||
|
arduino --board $BOARD --save-prefs
|
||||||
|
arduino --get-pref sketchbook.path
|
||||||
|
arduino --pref update.check=false
|
||||||
|
|
||||||
|
- name: build example
|
||||||
|
timeout-minutes: 20
|
||||||
|
run: |
|
||||||
|
export DISPLAY=:1.0
|
||||||
|
export PATH="$HOME/arduino_ide:$PATH"
|
||||||
|
source $GITHUB_WORKSPACE/travis/common.sh
|
||||||
|
cd $GITHUB_WORKSPACE
|
||||||
|
build_sketch arduino $SKETCH
|
||||||
|
|
||||||
|
done:
|
||||||
|
needs: [prepare_ide, prepare_example_json, build, check_version_files]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Done
|
||||||
|
run: |
|
||||||
|
echo DONE
|
@ -43,9 +43,3 @@ notifications:
|
|||||||
email:
|
email:
|
||||||
on_success: change
|
on_success: change
|
||||||
on_failure: change
|
on_failure: change
|
||||||
webhooks:
|
|
||||||
urls:
|
|
||||||
- https://webhooks.gitter.im/e/1aa78fbe15080b0c2e37
|
|
||||||
on_success: change # options: [always|never|change] default: always
|
|
||||||
on_failure: always # options: [always|never|change] default: always
|
|
||||||
on_start: false # default: false
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
WebSocket Server and Client for Arduino [](https://travis-ci.com/Links2004/arduinoWebSockets)
|
WebSocket Server and Client for Arduino [](https://github.com/Links2004/arduinoWebSockets/actions?query=workflow%3ACI+branch%3Amaster)
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
a WebSocket Server and Client for Arduino based on RFC6455.
|
a WebSocket Server and Client for Arduino based on RFC6455.
|
||||||
|
@ -90,6 +90,10 @@ void setup() {
|
|||||||
delay(100);
|
delay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//When using BearSSL, client certificate and private key can be set:
|
||||||
|
//webSocket.setSSLClientCertKey(clientCert, clientPrivateKey);
|
||||||
|
//clientCert and clientPrivateKey can be of types (const char *, const char *) , or of types (BearSSL::X509List, BearSSL::PrivateKey)
|
||||||
|
|
||||||
webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT);
|
webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT);
|
||||||
webSocket.onEvent(webSocketEvent);
|
webSocket.onEvent(webSocketEvent);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length)
|
|||||||
break;
|
break;
|
||||||
case sIOtype_CONNECT:
|
case sIOtype_CONNECT:
|
||||||
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
||||||
|
|
||||||
|
// join default namespace (no auto join in Socket.IO V3)
|
||||||
|
socketIO.send(sIOtype_CONNECT, "/");
|
||||||
break;
|
break;
|
||||||
case sIOtype_EVENT:
|
case sIOtype_EVENT:
|
||||||
USE_SERIAL.printf("[IOc] get event: %s\n", payload);
|
USE_SERIAL.printf("[IOc] get event: %s\n", payload);
|
||||||
|
@ -30,6 +30,9 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length)
|
|||||||
break;
|
break;
|
||||||
case sIOtype_CONNECT:
|
case sIOtype_CONNECT:
|
||||||
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
||||||
|
|
||||||
|
// join default namespace (no auto join in Socket.IO V3)
|
||||||
|
socketIO.send(sIOtype_CONNECT, "/");
|
||||||
break;
|
break;
|
||||||
case sIOtype_EVENT:
|
case sIOtype_EVENT:
|
||||||
{
|
{
|
||||||
|
103
examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino
Normal file
103
examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* WebSocketServerHooked.ino
|
||||||
|
*
|
||||||
|
* Created on: 22.05.2015
|
||||||
|
* Hooked on: 28.10.2020
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WiFiMulti.h>
|
||||||
|
#include <WebSockets4WebServer.h>
|
||||||
|
#include <Hash.h>
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
|
||||||
|
ESP8266WiFiMulti WiFiMulti;
|
||||||
|
|
||||||
|
ESP8266WebServer server(80);
|
||||||
|
WebSockets4WebServer webSocket;
|
||||||
|
|
||||||
|
#define USE_SERIAL Serial
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
server.on("/", []() {
|
||||||
|
server.send(200, "text/plain", "I am a regular webserver on port 80!\r\n");
|
||||||
|
server.send(200, "text/plain", "I am also a websocket server on '/ws' on the same port 80\r\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.addHook(webSocket.hookForWebserver("/ws", webSocketEvent));
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
Serial.println("HTTP server started on port 80");
|
||||||
|
Serial.println("WebSocket server started on the same port");
|
||||||
|
Serial.printf("my network address is either 'arduinoWebsockets.local' (mDNS) or '%s'\n", WiFi.localIP().toString().c_str());
|
||||||
|
|
||||||
|
if (!MDNS.begin("arduinoWebsockets")) {
|
||||||
|
Serial.println("Error setting up MDNS responder!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
server.handleClient();
|
||||||
|
webSocket.loop();
|
||||||
|
MDNS.update();
|
||||||
|
}
|
20
examples/esp8266/WebSocketServerHooked/emu
Executable file
20
examples/esp8266/WebSocketServerHooked/emu
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# linux script to compile&run arduinoWebSockets in a mock environment
|
||||||
|
|
||||||
|
if [ -z "$ESP8266ARDUINO" ]; then
|
||||||
|
echo "please set ESP8266ARDUINO env-var to where esp8266/arduino sits"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
where=$(pwd)
|
||||||
|
|
||||||
|
cd $ESP8266ARDUINO/tests/host/
|
||||||
|
|
||||||
|
make -j FORCE32=0 \
|
||||||
|
ULIBDIRS=../../libraries/Hash/:~/dev/proj/arduino/libraries/arduinoWebSockets \
|
||||||
|
${where}/WebSocketServerHooked
|
||||||
|
|
||||||
|
valgrind ./bin/WebSocketServerHooked/WebSocketServerHooked -b "$@"
|
45
examples/esp8266/WebSocketServerHooked/ws-testclient.py
Executable file
45
examples/esp8266/WebSocketServerHooked/ws-testclient.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# python websocket client to test with
|
||||||
|
# emulator: server is at ws://127.0.0.1:9080/ws
|
||||||
|
# esp8266: server is at ws:///ws
|
||||||
|
# (uncomment the right line below)
|
||||||
|
|
||||||
|
#uri = "ws://127.0.0.1:9080/ws"
|
||||||
|
uri = "ws://arduinoWebsockets.local/ws"
|
||||||
|
|
||||||
|
import websocket
|
||||||
|
try:
|
||||||
|
import thread
|
||||||
|
except ImportError:
|
||||||
|
import _thread as thread
|
||||||
|
import time
|
||||||
|
|
||||||
|
def on_message(ws, message):
|
||||||
|
print("message");
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
def on_error(ws, error):
|
||||||
|
print("error")
|
||||||
|
print(error)
|
||||||
|
|
||||||
|
def on_close(ws):
|
||||||
|
print("### closed ###")
|
||||||
|
|
||||||
|
def on_open(ws):
|
||||||
|
print("opened")
|
||||||
|
def run(*args):
|
||||||
|
for i in range(3):
|
||||||
|
time.sleep(1)
|
||||||
|
ws.send("Hello %d" % i)
|
||||||
|
time.sleep(1)
|
||||||
|
ws.close()
|
||||||
|
print("thread terminating...")
|
||||||
|
thread.start_new_thread(run, ())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
websocket.enableTrace(True)
|
||||||
|
ws = websocket.WebSocketApp(uri, on_message = on_message, on_error = on_error, on_close = on_close)
|
||||||
|
ws.on_open = on_open
|
||||||
|
ws.run_forever()
|
26
library.json
26
library.json
@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "WebSockets",
|
|
||||||
"description": "WebSocket Server and Client for Arduino based on RFC6455",
|
|
||||||
"keywords": "wifi, http, web, server, client, websocket",
|
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
"maintainer": true,
|
||||||
"name": "Markus Sattler",
|
"name": "Markus Sattler",
|
||||||
"url": "https://github.com/Links2004",
|
"url": "https://github.com/Links2004"
|
||||||
"maintainer": true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"repository": {
|
"description": "WebSocket Server and Client for Arduino based on RFC6455",
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Links2004/arduinoWebSockets.git"
|
|
||||||
},
|
|
||||||
"version": "2.3.0",
|
|
||||||
"license": "LGPL-2.1",
|
|
||||||
"export": {
|
"export": {
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"tests"
|
"tests"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "atmelavr, espressif8266, espressif32"
|
"keywords": "wifi, http, web, server, client, websocket",
|
||||||
}
|
"license": "LGPL-2.1",
|
||||||
|
"name": "WebSockets",
|
||||||
|
"platforms": "atmelavr, espressif8266, espressif32",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Links2004/arduinoWebSockets.git"
|
||||||
|
},
|
||||||
|
"version": "2.3.5"
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
name=WebSockets
|
name=WebSockets
|
||||||
version=2.3.0
|
version=2.3.5
|
||||||
author=Markus Sattler
|
author=Markus Sattler
|
||||||
maintainer=Markus Sattler
|
maintainer=Markus Sattler
|
||||||
sentence=WebSockets for Arduino (Server + Client)
|
sentence=WebSockets for Arduino (Server + Client)
|
||||||
|
@ -18,11 +18,59 @@ SocketIOclient::~SocketIOclient() {
|
|||||||
void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) {
|
void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) {
|
||||||
WebSocketsClient::beginSocketIO(host, port, url, protocol);
|
WebSocketsClient::beginSocketIO(host, port, url, protocol);
|
||||||
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) {
|
void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) {
|
||||||
WebSocketsClient::beginSocketIO(host, port, url, protocol);
|
WebSocketsClient::beginSocketIO(host, port, url, protocol);
|
||||||
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
#if defined(HAS_SSL)
|
||||||
|
void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) {
|
||||||
|
WebSocketsClient::beginSocketIOSSL(host, port, url, protocol);
|
||||||
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) {
|
||||||
|
WebSocketsClient::beginSocketIOSSL(host, port, url, protocol);
|
||||||
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
#if defined(SSL_BARESSL)
|
||||||
|
void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
|
||||||
|
WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol);
|
||||||
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) {
|
||||||
|
WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol);
|
||||||
|
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIOclient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) {
|
||||||
|
WebSocketsClient::setSSLClientCertKey(clientCert, clientPrivateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIOclient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) {
|
||||||
|
WebSocketsClient::setSSLClientCertKey(clientCert, clientPrivateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SocketIOclient::configureEIOping(bool disableHeartbeat) {
|
||||||
|
_disableHeartbeat = disableHeartbeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIOclient::initClient(void) {
|
||||||
|
if(_client.cUrl.indexOf("EIO=4") != -1) {
|
||||||
|
DEBUG_WEBSOCKETS("[wsIOc] found EIO=4 disable EIO ping on client\n");
|
||||||
|
configureEIOping(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +99,7 @@ bool SocketIOclient::send(socketIOmessageType_t type, uint8_t * payload, size_t
|
|||||||
if(length == 0) {
|
if(length == 0) {
|
||||||
length = strlen((const char *)payload);
|
length = strlen((const char *)payload);
|
||||||
}
|
}
|
||||||
if(clientIsConnected(&_client)) {
|
if(clientIsConnected(&_client) && _client.status == WSC_CONNECTED) {
|
||||||
if(!headerToPayload) {
|
if(!headerToPayload) {
|
||||||
// webSocket Header
|
// webSocket Header
|
||||||
ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true);
|
ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true);
|
||||||
@ -118,8 +166,8 @@ bool SocketIOclient::sendEVENT(String & payload) {
|
|||||||
void SocketIOclient::loop(void) {
|
void SocketIOclient::loop(void) {
|
||||||
WebSocketsClient::loop();
|
WebSocketsClient::loop();
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) {
|
if(!_disableHeartbeat && (t - _lastHeartbeat) > EIO_HEARTBEAT_INTERVAL) {
|
||||||
_lastConnectionFail = t;
|
_lastHeartbeat = t;
|
||||||
DEBUG_WEBSOCKETS("[wsIOc] send ping\n");
|
DEBUG_WEBSOCKETS("[wsIOc] send ping\n");
|
||||||
WebSocketsClient::sendTXT(eIOtype_PING);
|
WebSocketsClient::sendTXT(eIOtype_PING);
|
||||||
}
|
}
|
||||||
@ -135,6 +183,7 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng
|
|||||||
DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload);
|
DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload);
|
||||||
// send message to server when Connected
|
// send message to server when Connected
|
||||||
// Engine.io upgrade confirmation message (required)
|
// Engine.io upgrade confirmation message (required)
|
||||||
|
WebSocketsClient::sendTXT("2probe");
|
||||||
WebSocketsClient::sendTXT(eIOtype_UPGRADE);
|
WebSocketsClient::sendTXT(eIOtype_UPGRADE);
|
||||||
runIOCbEvent(sIOtype_CONNECT, payload, length);
|
runIOCbEvent(sIOtype_CONNECT, payload, length);
|
||||||
} break;
|
} break;
|
||||||
@ -165,6 +214,8 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng
|
|||||||
DEBUG_WEBSOCKETS("[wsIOc] get event (%d): %s\n", lData, data);
|
DEBUG_WEBSOCKETS("[wsIOc] get event (%d): %s\n", lData, data);
|
||||||
break;
|
break;
|
||||||
case sIOtype_CONNECT:
|
case sIOtype_CONNECT:
|
||||||
|
DEBUG_WEBSOCKETS("[wsIOc] connected (%d): %s\n", lData, data);
|
||||||
|
return;
|
||||||
case sIOtype_DISCONNECT:
|
case sIOtype_DISCONNECT:
|
||||||
case sIOtype_ACK:
|
case sIOtype_ACK:
|
||||||
case sIOtype_ERROR:
|
case sIOtype_ERROR:
|
||||||
|
@ -49,6 +49,16 @@ class SocketIOclient : protected WebSocketsClient {
|
|||||||
void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
||||||
void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||||
|
|
||||||
|
#ifdef HAS_SSL
|
||||||
|
void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
||||||
|
void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||||
|
#ifndef SSL_AXTLS
|
||||||
|
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
|
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
|
void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL);
|
||||||
|
void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
bool isConnected(void);
|
bool isConnected(void);
|
||||||
|
|
||||||
void onEvent(SocketIOclientEvent cbEvent);
|
void onEvent(SocketIOclientEvent cbEvent);
|
||||||
@ -67,7 +77,10 @@ class SocketIOclient : protected WebSocketsClient {
|
|||||||
|
|
||||||
void loop(void);
|
void loop(void);
|
||||||
|
|
||||||
|
void configureEIOping(bool disableHeartbeat = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool _disableHeartbeat = false;
|
||||||
uint64_t _lastHeartbeat = 0;
|
uint64_t _lastHeartbeat = 0;
|
||||||
SocketIOclientEvent _cbEvent;
|
SocketIOclientEvent _cbEvent;
|
||||||
virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
|
virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
|
||||||
@ -76,6 +89,8 @@ class SocketIOclient : protected WebSocketsClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initClient(void);
|
||||||
|
|
||||||
// Handeling events from websocket layer
|
// Handeling events from websocket layer
|
||||||
virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) {
|
virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||||
handleCbEvent(type, payload, length);
|
handleCbEvent(type, payload, length);
|
||||||
|
@ -644,7 +644,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
|||||||
} else {
|
} else {
|
||||||
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
|
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
|
||||||
}
|
}
|
||||||
if (n > 0) {
|
if(n > 0) {
|
||||||
WEBSOCKETS_YIELD();
|
WEBSOCKETS_YIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -698,7 +698,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) {
|
|||||||
} else {
|
} else {
|
||||||
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
|
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
|
||||||
}
|
}
|
||||||
if (n > 0) {
|
if(n > 0) {
|
||||||
WEBSOCKETS_YIELD();
|
WEBSOCKETS_YIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,15 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "WebSocketsVersion.h"
|
||||||
|
|
||||||
#ifndef NODEBUG_WEBSOCKETS
|
#ifndef NODEBUG_WEBSOCKETS
|
||||||
#ifdef DEBUG_ESP_PORT
|
#ifdef DEBUG_ESP_PORT
|
||||||
#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf(__VA_ARGS__)
|
#define DEBUG_WEBSOCKETS(...) \
|
||||||
|
{ \
|
||||||
|
DEBUG_ESP_PORT.printf(__VA_ARGS__); \
|
||||||
|
DEBUG_ESP_PORT.flush(); \
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
|
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
|
||||||
#endif
|
#endif
|
||||||
@ -211,6 +217,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
WSC_NOT_CONNECTED,
|
WSC_NOT_CONNECTED,
|
||||||
WSC_HEADER,
|
WSC_HEADER,
|
||||||
|
WSC_BODY,
|
||||||
WSC_CONNECTED
|
WSC_CONNECTED
|
||||||
} WSclientsStatus_t;
|
} WSclientsStatus_t;
|
||||||
|
|
||||||
@ -254,34 +261,44 @@ typedef struct {
|
|||||||
} WSMessageHeader_t;
|
} WSMessageHeader_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t num; ///< connection number
|
void init(uint8_t num,
|
||||||
|
uint32_t pingInterval,
|
||||||
|
uint32_t pongTimeout,
|
||||||
|
uint8_t disconnectTimeoutCount) {
|
||||||
|
this->num = num;
|
||||||
|
this->pingInterval = pingInterval;
|
||||||
|
this->pongTimeout = pongTimeout;
|
||||||
|
this->disconnectTimeoutCount = disconnectTimeoutCount;
|
||||||
|
}
|
||||||
|
|
||||||
WSclientsStatus_t status;
|
uint8_t num = 0; ///< connection number
|
||||||
|
|
||||||
WEBSOCKETS_NETWORK_CLASS * tcp;
|
WSclientsStatus_t status = WSC_NOT_CONNECTED;
|
||||||
|
|
||||||
bool isSocketIO; ///< client for socket.io server
|
WEBSOCKETS_NETWORK_CLASS * tcp = nullptr;
|
||||||
|
|
||||||
|
bool isSocketIO = false; ///< client for socket.io server
|
||||||
|
|
||||||
#if defined(HAS_SSL)
|
#if defined(HAS_SSL)
|
||||||
bool isSSL; ///< run in ssl mode
|
bool isSSL = false; ///< run in ssl mode
|
||||||
WEBSOCKETS_NETWORK_SSL_CLASS * ssl;
|
WEBSOCKETS_NETWORK_SSL_CLASS * ssl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String cUrl; ///< http url
|
String cUrl; ///< http url
|
||||||
uint16_t cCode; ///< http code
|
uint16_t cCode = 0; ///< http code
|
||||||
|
|
||||||
bool cIsClient = false; ///< will be used for masking
|
bool cIsClient = false; ///< will be used for masking
|
||||||
bool cIsUpgrade; ///< Connection == Upgrade
|
bool cIsUpgrade = false; ///< Connection == Upgrade
|
||||||
bool cIsWebsocket; ///< Upgrade == websocket
|
bool cIsWebsocket = false; ///< Upgrade == websocket
|
||||||
|
|
||||||
String cSessionId; ///< client Set-Cookie (session id)
|
String cSessionId; ///< client Set-Cookie (session id)
|
||||||
String cKey; ///< client Sec-WebSocket-Key
|
String cKey; ///< client Sec-WebSocket-Key
|
||||||
String cAccept; ///< client Sec-WebSocket-Accept
|
String cAccept; ///< client Sec-WebSocket-Accept
|
||||||
String cProtocol; ///< client Sec-WebSocket-Protocol
|
String cProtocol; ///< client Sec-WebSocket-Protocol
|
||||||
String cExtensions; ///< client Sec-WebSocket-Extensions
|
String cExtensions; ///< client Sec-WebSocket-Extensions
|
||||||
uint16_t cVersion; ///< client Sec-WebSocket-Version
|
uint16_t cVersion = 0; ///< client Sec-WebSocket-Version
|
||||||
|
|
||||||
uint8_t cWsRXsize; ///< State of the RX
|
uint8_t cWsRXsize = 0; ///< State of the RX
|
||||||
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
|
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
|
||||||
WSMessageHeader_t cWsHeaderDecode;
|
WSMessageHeader_t cWsHeaderDecode;
|
||||||
|
|
||||||
@ -290,15 +307,15 @@ typedef struct {
|
|||||||
|
|
||||||
String extraHeaders;
|
String extraHeaders;
|
||||||
|
|
||||||
bool cHttpHeadersValid; ///< non-websocket http header validity indicator
|
bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator
|
||||||
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count
|
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count
|
||||||
|
|
||||||
bool pongReceived;
|
bool pongReceived = false;
|
||||||
uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active"
|
uint32_t pingInterval = 0; // how often ping will be sent, 0 means "heartbeat is not active"
|
||||||
uint32_t lastPing; // millis when last pong has been received
|
uint32_t lastPing = 0; // millis when last pong has been received
|
||||||
uint32_t pongTimeout; // interval in millis after which pong is considered to timeout
|
uint32_t pongTimeout = 0; // interval in millis after which pong is considered to timeout
|
||||||
uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect"
|
uint8_t disconnectTimeoutCount = 0; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect"
|
||||||
uint8_t pongTimeoutCount; // current pong timeout count
|
uint8_t pongTimeoutCount = 0; // current pong timeout count
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||||
String cHttpLine; ///< HTTP header lines
|
String cHttpLine; ///< HTTP header lines
|
||||||
|
80
src/WebSockets4WebServer.h
Normal file
80
src/WebSockets4WebServer.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @file WebSocketsServer.cpp
|
||||||
|
* @date 28.10.2020
|
||||||
|
* @author Markus Sattler & esp8266/arduino community
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Markus Sattler. All rights reserved.
|
||||||
|
* This file is part of the WebSockets for Arduino.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WEBSOCKETS4WEBSERVER_H
|
||||||
|
#define __WEBSOCKETS4WEBSERVER_H
|
||||||
|
|
||||||
|
#include <WebSocketsServer.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
|
||||||
|
#if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK
|
||||||
|
|
||||||
|
class WebSockets4WebServer : public WebSocketsServerCore {
|
||||||
|
public:
|
||||||
|
WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino")
|
||||||
|
: WebSocketsServerCore(origin, protocol) {
|
||||||
|
begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) {
|
||||||
|
onEvent(event);
|
||||||
|
|
||||||
|
return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) {
|
||||||
|
(void)contentType;
|
||||||
|
|
||||||
|
if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) {
|
||||||
|
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate a WiFiClient copy (like in WebSocketsServer::handleNewClients())
|
||||||
|
WEBSOCKETS_NETWORK_CLASS * newTcpClient = new WEBSOCKETS_NETWORK_CLASS(*tcpClient);
|
||||||
|
|
||||||
|
// Then initialize a new WSclient_t (like in WebSocketsServer::handleNewClient())
|
||||||
|
WSclient_t * client = handleNewClient(newTcpClient);
|
||||||
|
|
||||||
|
if(client) {
|
||||||
|
// give "GET <url>"
|
||||||
|
String headerLine;
|
||||||
|
headerLine.reserve(url.length() + 5);
|
||||||
|
headerLine = "GET ";
|
||||||
|
headerLine += url;
|
||||||
|
handleHeader(client, &headerLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell webserver to not close but forget about this client
|
||||||
|
return ESP8266WebServer::CLIENT_IS_GIVEN;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK
|
||||||
|
|
||||||
|
#ifndef WEBSERVER_HAS_HOOK
|
||||||
|
#error Your current Framework / Arduino core version does not support Webserver Hook Functions
|
||||||
|
#else
|
||||||
|
#error Your Hardware Platform does not support Webserver Hook Functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK
|
||||||
|
|
||||||
|
#endif // __WEBSOCKETS4WEBSERVER_H
|
@ -86,6 +86,8 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url,
|
|||||||
|
|
||||||
_lastConnectionFail = 0;
|
_lastConnectionFail = 0;
|
||||||
_lastHeaderSent = 0;
|
_lastHeaderSent = 0;
|
||||||
|
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client] Websocket Version: " WEBSOCKETS_VERSION "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) {
|
void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) {
|
||||||
@ -122,12 +124,6 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u
|
|||||||
_fingerprint = fingerprint;
|
_fingerprint = fingerprint;
|
||||||
_CA_cert = NULL;
|
_CA_cert = NULL;
|
||||||
}
|
}
|
||||||
void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
|
|
||||||
begin(host, port, url, protocol);
|
|
||||||
_client.isSSL = true;
|
|
||||||
_fingerprint = SSL_FINGERPRINT_NULL;
|
|
||||||
_CA_cert = new BearSSL::X509List(CA_cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) {
|
void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) {
|
||||||
begin(host, port, url, protocol);
|
begin(host, port, url, protocol);
|
||||||
@ -135,6 +131,20 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch
|
|||||||
_fingerprint = SSL_FINGERPRINT_NULL;
|
_fingerprint = SSL_FINGERPRINT_NULL;
|
||||||
_CA_cert = CA_cert;
|
_CA_cert = CA_cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
|
||||||
|
beginSslWithCA(host, port, url, new BearSSL::X509List(CA_cert), protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocketsClient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) {
|
||||||
|
_client_cert = clientCert;
|
||||||
|
_client_key = clientPrivateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocketsClient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) {
|
||||||
|
setSSLClientCertKey(new BearSSL::X509List(clientCert), new BearSSL::PrivateKey(clientPrivateKey));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SSL_AXTLS
|
#endif // SSL_AXTLS
|
||||||
#endif // HAS_SSL
|
#endif // HAS_SSL
|
||||||
|
|
||||||
@ -159,17 +169,28 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url,
|
|||||||
beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str());
|
beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SSL_BARESSL)
|
||||||
|
void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) {
|
||||||
|
begin(host, port, url, protocol);
|
||||||
|
_client.isSocketIO = true;
|
||||||
|
_client.isSSL = true;
|
||||||
|
_fingerprint = SSL_FINGERPRINT_NULL;
|
||||||
|
_CA_cert = CA_cert;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
|
void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) {
|
||||||
begin(host, port, url, protocol);
|
begin(host, port, url, protocol);
|
||||||
_client.isSocketIO = true;
|
_client.isSocketIO = true;
|
||||||
_client.isSSL = true;
|
_client.isSSL = true;
|
||||||
_fingerprint = SSL_FINGERPRINT_NULL;
|
_fingerprint = SSL_FINGERPRINT_NULL;
|
||||||
#if defined(SSL_AXTLS)
|
#if defined(SSL_BARESSL)
|
||||||
_CA_cert = CA_cert;
|
|
||||||
#else
|
|
||||||
_CA_cert = new BearSSL::X509List(CA_cert);
|
_CA_cert = new BearSSL::X509List(CA_cert);
|
||||||
|
#else
|
||||||
|
_CA_cert = CA_cert;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
@ -208,11 +229,18 @@ void WebSocketsClient::loop(void) {
|
|||||||
#else
|
#else
|
||||||
#error setCACert not implemented
|
#error setCACert not implemented
|
||||||
#endif
|
#endif
|
||||||
#if defined(SSL_BARESSL)
|
#if defined(ESP32)
|
||||||
} else if(_fingerprint) {
|
} else if(!SSL_FINGERPRINT_IS_SET) {
|
||||||
|
_client.ssl->setInsecure();
|
||||||
|
#elif defined(SSL_BARESSL)
|
||||||
|
} else if(SSL_FINGERPRINT_IS_SET) {
|
||||||
_client.ssl->setFingerprint(_fingerprint);
|
_client.ssl->setFingerprint(_fingerprint);
|
||||||
} else {
|
} else {
|
||||||
_client.ssl->setInsecure();
|
_client.ssl->setInsecure();
|
||||||
|
}
|
||||||
|
if(_client_cert && _client_key) {
|
||||||
|
_client.ssl->setClientRSACert(_client_cert, _client_key);
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client] setting client certificate and key");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -482,7 +510,8 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) {
|
|||||||
client->cIsWebsocket = false;
|
client->cIsWebsocket = false;
|
||||||
client->cSessionId = "";
|
client->cSessionId = "";
|
||||||
|
|
||||||
client->status = WSC_NOT_CONNECTED;
|
client->status = WSC_NOT_CONNECTED;
|
||||||
|
_lastConnectionFail = millis();
|
||||||
|
|
||||||
DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n");
|
DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n");
|
||||||
if(event) {
|
if(event) {
|
||||||
@ -525,12 +554,13 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) {
|
|||||||
* Handel incomming data from Client
|
* Handel incomming data from Client
|
||||||
*/
|
*/
|
||||||
void WebSocketsClient::handleClientData(void) {
|
void WebSocketsClient::handleClientData(void) {
|
||||||
if(_client.status == WSC_HEADER && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) {
|
if((_client.status == WSC_HEADER || _client.status == WSC_BODY) && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) {
|
||||||
DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n");
|
DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n");
|
||||||
clientDisconnect(&_client);
|
clientDisconnect(&_client);
|
||||||
WEBSOCKETS_YIELD();
|
WEBSOCKETS_YIELD();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = _client.tcp->available();
|
int len = _client.tcp->available();
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
switch(_client.status) {
|
switch(_client.status) {
|
||||||
@ -538,6 +568,12 @@ void WebSocketsClient::handleClientData(void) {
|
|||||||
String headerLine = _client.tcp->readStringUntil('\n');
|
String headerLine = _client.tcp->readStringUntil('\n');
|
||||||
handleHeader(&_client, &headerLine);
|
handleHeader(&_client, &headerLine);
|
||||||
} break;
|
} break;
|
||||||
|
case WSC_BODY: {
|
||||||
|
char buf[256] = { 0 };
|
||||||
|
_client.tcp->readBytes(&buf[0], std::min((size_t)len, sizeof(buf)));
|
||||||
|
String bodyLine = buf;
|
||||||
|
handleHeader(&_client, &bodyLine);
|
||||||
|
} break;
|
||||||
case WSC_CONNECTED:
|
case WSC_CONNECTED:
|
||||||
WebSockets::handleWebsocket(&_client);
|
WebSockets::handleWebsocket(&_client);
|
||||||
break;
|
break;
|
||||||
@ -613,7 +649,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add extra headers; by default this includes "Origin: file://"
|
// add extra headers; by default this includes "Origin: file://"
|
||||||
if(client->extraHeaders) {
|
if(client->extraHeaders.length() > 0) {
|
||||||
handshake += client->extraHeaders + NEW_LINE;
|
handshake += client->extraHeaders + NEW_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,6 +685,22 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
|
|||||||
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
||||||
headerLine->trim(); // remove \r
|
headerLine->trim(); // remove \r
|
||||||
|
|
||||||
|
// this code handels the http body for Socket.IO V3 requests
|
||||||
|
if(headerLine->length() > 0 && client->isSocketIO && client->status == WSC_BODY && client->cSessionId.length() == 0) {
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] socket.io json: %s\n", headerLine->c_str());
|
||||||
|
String sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
|
||||||
|
if(headerLine->indexOf(sid_begin) > -1) {
|
||||||
|
int start = headerLine->indexOf(sid_begin) + sid_begin.length();
|
||||||
|
int end = headerLine->indexOf('"', start);
|
||||||
|
client->cSessionId = headerLine->substring(start, end);
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
|
||||||
|
|
||||||
|
// Trigger websocket connection code path
|
||||||
|
*headerLine = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// headle HTTP header
|
||||||
if(headerLine->length() > 0) {
|
if(headerLine->length() > 0) {
|
||||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());
|
||||||
|
|
||||||
@ -682,7 +734,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
|||||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
|
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) {
|
||||||
client->cVersion = headerValue.toInt();
|
client->cVersion = headerValue.toInt();
|
||||||
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) {
|
} else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) {
|
||||||
if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) {
|
if(headerValue.indexOf(';') > -1) {
|
||||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";"));
|
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";"));
|
||||||
} else {
|
} else {
|
||||||
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
|
client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1);
|
||||||
@ -713,6 +765,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
|||||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion);
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion);
|
||||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str());
|
||||||
|
|
||||||
|
if(client->isSocketIO && client->cSessionId.length() == 0 && clientIsConnected(client)) {
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still missing cSessionId try socket.io V3\n");
|
||||||
|
client->status = WSC_BODY;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
client->status = WSC_HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
|
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
|
||||||
|
|
||||||
if(ok) {
|
if(ok) {
|
||||||
@ -754,15 +814,18 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
|
|||||||
|
|
||||||
runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length());
|
runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length());
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
} else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) {
|
} else if(client->isSocketIO) {
|
||||||
if(_client.tcp->available()) {
|
if(client->cSessionId.length() > 0) {
|
||||||
// read not needed data
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] found cSessionId\n");
|
||||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available());
|
if(clientIsConnected(client) && _client.tcp->available()) {
|
||||||
while(_client.tcp->available() > 0) {
|
// read not needed data
|
||||||
_client.tcp->read();
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available());
|
||||||
|
while(_client.tcp->available() > 0) {
|
||||||
|
_client.tcp->read();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sendHeader(client);
|
||||||
}
|
}
|
||||||
sendHeader(client);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
|
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
|
||||||
@ -805,14 +868,14 @@ void WebSocketsClient::connectedCb() {
|
|||||||
|
|
||||||
#if defined(HAS_SSL)
|
#if defined(HAS_SSL)
|
||||||
#if defined(SSL_AXTLS) || defined(ESP32)
|
#if defined(SSL_AXTLS) || defined(ESP32)
|
||||||
if(_client.isSSL && _fingerprint.length()) {
|
if(_client.isSSL && SSL_FINGERPRINT_IS_SET) {
|
||||||
if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) {
|
if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) {
|
||||||
DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n");
|
DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n");
|
||||||
WebSockets::clientDisconnect(&_client, 1000);
|
WebSockets::clientDisconnect(&_client, 1000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(_client.isSSL && _fingerprint) {
|
if(_client.isSSL && SSL_FINGERPRINT_IS_SET) {
|
||||||
#endif
|
#endif
|
||||||
} else if(_client.isSSL && !_CA_cert) {
|
} else if(_client.isSSL && !_CA_cert) {
|
||||||
#if defined(SSL_BARESSL)
|
#if defined(SSL_BARESSL)
|
||||||
@ -885,6 +948,9 @@ void WebSocketsClient::handleHBPing() {
|
|||||||
if(sendPing()) {
|
if(sendPing()) {
|
||||||
_client.lastPing = millis();
|
_client.lastPing = millis();
|
||||||
_client.pongReceived = false;
|
_client.pongReceived = false;
|
||||||
|
} else {
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Client] sending HB ping failed\n");
|
||||||
|
WebSockets::clientDisconnect(&_client, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ class WebSocketsClient : protected WebSockets {
|
|||||||
#else
|
#else
|
||||||
void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino");
|
void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino");
|
||||||
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
|
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
|
void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL);
|
||||||
|
void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL);
|
||||||
#endif
|
#endif
|
||||||
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino");
|
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
#endif
|
#endif
|
||||||
@ -59,7 +61,11 @@ class WebSocketsClient : protected WebSockets {
|
|||||||
#if defined(HAS_SSL)
|
#if defined(HAS_SSL)
|
||||||
void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
|
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");
|
void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
|
||||||
|
|
||||||
void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
|
void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
|
#if defined(SSL_BARESSL)
|
||||||
|
void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
@ -106,10 +112,14 @@ class WebSocketsClient : protected WebSockets {
|
|||||||
#ifdef SSL_AXTLS
|
#ifdef SSL_AXTLS
|
||||||
String _fingerprint;
|
String _fingerprint;
|
||||||
const char * _CA_cert;
|
const char * _CA_cert;
|
||||||
|
#define SSL_FINGERPRINT_IS_SET (_fingerprint.length())
|
||||||
#define SSL_FINGERPRINT_NULL ""
|
#define SSL_FINGERPRINT_NULL ""
|
||||||
#else
|
#else
|
||||||
const uint8_t * _fingerprint;
|
const uint8_t * _fingerprint;
|
||||||
BearSSL::X509List * _CA_cert;
|
BearSSL::X509List * _CA_cert;
|
||||||
|
BearSSL::X509List * _client_cert;
|
||||||
|
BearSSL::PrivateKey * _client_key;
|
||||||
|
#define SSL_FINGERPRINT_IS_SET (_fingerprint != NULL)
|
||||||
#define SSL_FINGERPRINT_NULL NULL
|
#define SSL_FINGERPRINT_NULL NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "WebSockets.h"
|
#include "WebSockets.h"
|
||||||
#include "WebSocketsServer.h"
|
#include "WebSocketsServer.h"
|
||||||
|
|
||||||
WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) {
|
WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) {
|
||||||
_port = port;
|
|
||||||
_origin = origin;
|
_origin = origin;
|
||||||
_protocol = protocol;
|
_protocol = protocol;
|
||||||
_runnning = false;
|
_runnning = false;
|
||||||
@ -34,25 +33,28 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
|
|||||||
_pongTimeout = 0;
|
_pongTimeout = 0;
|
||||||
_disconnectTimeoutCount = 0;
|
_disconnectTimeoutCount = 0;
|
||||||
|
|
||||||
_server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port);
|
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
|
||||||
_server->onClient([](void * s, AsyncClient * c) {
|
|
||||||
((WebSocketsServer *)s)->newClient(new AsyncTCPbuffer(c));
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_cbEvent = NULL;
|
_cbEvent = NULL;
|
||||||
|
|
||||||
_httpHeaderValidationFunc = NULL;
|
_httpHeaderValidationFunc = NULL;
|
||||||
_mandatoryHttpHeaders = NULL;
|
_mandatoryHttpHeaders = NULL;
|
||||||
_mandatoryHttpHeaderCount = 0;
|
_mandatoryHttpHeaderCount = 0;
|
||||||
|
|
||||||
memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketsServer::~WebSocketsServer() {
|
WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const String & protocol)
|
||||||
|
: WebSocketsServerCore(origin, protocol) {
|
||||||
|
_port = port;
|
||||||
|
|
||||||
|
_server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port);
|
||||||
|
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||||
|
_server->onClient([](void * s, AsyncClient * c) {
|
||||||
|
((WebSocketsServerCore *)s)->newClient(new AsyncTCPbuffer(c));
|
||||||
|
},
|
||||||
|
this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketsServerCore::~WebSocketsServerCore() {
|
||||||
// disconnect all clients
|
// disconnect all clients
|
||||||
close();
|
close();
|
||||||
|
|
||||||
@ -62,42 +64,20 @@ WebSocketsServer::~WebSocketsServer() {
|
|||||||
_mandatoryHttpHeaderCount = 0;
|
_mandatoryHttpHeaderCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebSocketsServer::~WebSocketsServer() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called to initialize the Websocket server
|
* called to initialize the Websocket server
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::begin(void) {
|
void WebSocketsServerCore::begin(void) {
|
||||||
WSclient_t * client;
|
// adjust clients storage:
|
||||||
|
// _clients[i]'s constructor are already called,
|
||||||
// init client storage
|
// all its members are initialized to their default value,
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
// except the ones explicitly detailed in WSclient_t() constructor.
|
||||||
client = &_clients[i];
|
// Then we need to initialize some members to non-trivial values:
|
||||||
|
for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
client->num = i;
|
_clients[i].init(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount);
|
||||||
client->status = WSC_NOT_CONNECTED;
|
|
||||||
client->tcp = NULL;
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
|
||||||
client->isSSL = false;
|
|
||||||
client->ssl = NULL;
|
|
||||||
#endif
|
|
||||||
client->cUrl = "";
|
|
||||||
client->cCode = 0;
|
|
||||||
client->cKey = "";
|
|
||||||
client->cProtocol = "";
|
|
||||||
client->cVersion = 0;
|
|
||||||
client->cIsUpgrade = false;
|
|
||||||
client->cIsWebsocket = false;
|
|
||||||
|
|
||||||
client->base64Authorization = "";
|
|
||||||
|
|
||||||
client->cWsRXsize = 0;
|
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
|
||||||
client->cHttpLine = "";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
client->pingInterval = _pingInterval;
|
|
||||||
client->pongTimeout = _pongTimeout;
|
|
||||||
client->disconnectTimeoutCount = _disconnectTimeoutCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -111,43 +91,26 @@ void WebSocketsServer::begin(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
_runnning = true;
|
_runnning = true;
|
||||||
_server->begin();
|
|
||||||
|
|
||||||
DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n");
|
DEBUG_WEBSOCKETS("[WS-Server] Websocket Version: " WEBSOCKETS_VERSION "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocketsServer::close(void) {
|
void WebSocketsServerCore::close(void) {
|
||||||
_runnning = false;
|
_runnning = false;
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
// restore _clients[] to their initial state
|
||||||
_server->close();
|
// before next call to ::begin()
|
||||||
#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
_server->end();
|
_clients[i] = WSclient_t();
|
||||||
#else
|
|
||||||
// TODO how to close server?
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
|
||||||
/**
|
|
||||||
* called in arduino loop
|
|
||||||
*/
|
|
||||||
void WebSocketsServer::loop(void) {
|
|
||||||
if(_runnning) {
|
|
||||||
WEBSOCKETS_YIELD();
|
|
||||||
handleNewClients();
|
|
||||||
WEBSOCKETS_YIELD();
|
|
||||||
handleClientData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set callback function
|
* set callback function
|
||||||
* @param cbEvent WebSocketServerEvent
|
* @param cbEvent WebSocketServerEvent
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) {
|
void WebSocketsServerCore::onEvent(WebSocketServerEvent cbEvent) {
|
||||||
_cbEvent = cbEvent;
|
_cbEvent = cbEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +120,7 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) {
|
|||||||
* @param mandatoryHttpHeaders[] const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed
|
* @param mandatoryHttpHeaders[] const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed
|
||||||
* @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array
|
* @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::onValidateHttpHeader(
|
void WebSocketsServerCore::onValidateHttpHeader(
|
||||||
WebSocketServerHttpHeaderValFunc validationFunc,
|
WebSocketServerHttpHeaderValFunc validationFunc,
|
||||||
const char * mandatoryHttpHeaders[],
|
const char * mandatoryHttpHeaders[],
|
||||||
size_t mandatoryHttpHeaderCount) {
|
size_t mandatoryHttpHeaderCount) {
|
||||||
@ -182,7 +145,7 @@ void WebSocketsServer::onValidateHttpHeader(
|
|||||||
* @param headerToPayload bool (see sendFrame for more details)
|
* @param headerToPayload bool (see sendFrame for more details)
|
||||||
* @return true if ok
|
* @return true if ok
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
||||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -196,19 +159,19 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::sendTXT(uint8_t num, const uint8_t * payload, size_t length) {
|
||||||
return sendTXT(num, (uint8_t *)payload, length);
|
return sendTXT(num, (uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) {
|
||||||
return sendTXT(num, (uint8_t *)payload, length, headerToPayload);
|
return sendTXT(num, (uint8_t *)payload, length, headerToPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) {
|
bool WebSocketsServerCore::sendTXT(uint8_t num, const char * payload, size_t length) {
|
||||||
return sendTXT(num, (uint8_t *)payload, length);
|
return sendTXT(num, (uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendTXT(uint8_t num, String & payload) {
|
bool WebSocketsServerCore::sendTXT(uint8_t num, String & payload) {
|
||||||
return sendTXT(num, (uint8_t *)payload.c_str(), payload.length());
|
return sendTXT(num, (uint8_t *)payload.c_str(), payload.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +182,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, String & payload) {
|
|||||||
* @param headerToPayload bool (see sendFrame for more details)
|
* @param headerToPayload bool (see sendFrame for more details)
|
||||||
* @return true if ok
|
* @return true if ok
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
if(length == 0) {
|
if(length == 0) {
|
||||||
@ -238,19 +201,19 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::broadcastTXT(const uint8_t * payload, size_t length) {
|
||||||
return broadcastTXT((uint8_t *)payload, length);
|
return broadcastTXT((uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::broadcastTXT(char * payload, size_t length, bool headerToPayload) {
|
||||||
return broadcastTXT((uint8_t *)payload, length, headerToPayload);
|
return broadcastTXT((uint8_t *)payload, length, headerToPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) {
|
bool WebSocketsServerCore::broadcastTXT(const char * payload, size_t length) {
|
||||||
return broadcastTXT((uint8_t *)payload, length);
|
return broadcastTXT((uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastTXT(String & payload) {
|
bool WebSocketsServerCore::broadcastTXT(String & payload) {
|
||||||
return broadcastTXT((uint8_t *)payload.c_str(), payload.length());
|
return broadcastTXT((uint8_t *)payload.c_str(), payload.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +225,7 @@ bool WebSocketsServer::broadcastTXT(String & payload) {
|
|||||||
* @param headerToPayload bool (see sendFrame for more details)
|
* @param headerToPayload bool (see sendFrame for more details)
|
||||||
* @return true if ok
|
* @return true if ok
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) {
|
||||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -273,7 +236,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::sendBIN(uint8_t num, const uint8_t * payload, size_t length) {
|
||||||
return sendBIN(num, (uint8_t *)payload, length);
|
return sendBIN(num, (uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +247,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng
|
|||||||
* @param headerToPayload bool (see sendFrame for more details)
|
* @param headerToPayload bool (see sendFrame for more details)
|
||||||
* @return true if ok
|
* @return true if ok
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) {
|
bool WebSocketsServerCore::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
@ -299,7 +262,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::broadcastBIN(const uint8_t * payload, size_t length) {
|
||||||
return broadcastBIN((uint8_t *)payload, length);
|
return broadcastBIN((uint8_t *)payload, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +273,7 @@ bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) {
|
|||||||
* @param length size_t
|
* @param length size_t
|
||||||
* @return true if ping is send out
|
* @return true if ping is send out
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::sendPing(uint8_t num, uint8_t * payload, size_t length) {
|
||||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -321,7 +284,7 @@ bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::sendPing(uint8_t num, String & payload) {
|
bool WebSocketsServerCore::sendPing(uint8_t num, String & payload) {
|
||||||
return sendPing(num, (uint8_t *)payload.c_str(), payload.length());
|
return sendPing(num, (uint8_t *)payload.c_str(), payload.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +294,7 @@ bool WebSocketsServer::sendPing(uint8_t num, String & payload) {
|
|||||||
* @param length size_t
|
* @param length size_t
|
||||||
* @return true if ping is send out
|
* @return true if ping is send out
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) {
|
bool WebSocketsServerCore::broadcastPing(uint8_t * payload, size_t length) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
@ -346,14 +309,14 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSocketsServer::broadcastPing(String & payload) {
|
bool WebSocketsServerCore::broadcastPing(String & payload) {
|
||||||
return broadcastPing((uint8_t *)payload.c_str(), payload.length());
|
return broadcastPing((uint8_t *)payload.c_str(), payload.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* disconnect all clients
|
* disconnect all clients
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::disconnect(void) {
|
void WebSocketsServerCore::disconnect(void) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
client = &_clients[i];
|
client = &_clients[i];
|
||||||
@ -367,7 +330,7 @@ void WebSocketsServer::disconnect(void) {
|
|||||||
* disconnect one client
|
* disconnect one client
|
||||||
* @param num uint8_t client id
|
* @param num uint8_t client id
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::disconnect(uint8_t num) {
|
void WebSocketsServerCore::disconnect(uint8_t num) {
|
||||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -382,7 +345,7 @@ void WebSocketsServer::disconnect(uint8_t num) {
|
|||||||
* @param user const char *
|
* @param user const char *
|
||||||
* @param password const char *
|
* @param password const char *
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::setAuthorization(const char * user, const char * password) {
|
void WebSocketsServerCore::setAuthorization(const char * user, const char * password) {
|
||||||
if(user && password) {
|
if(user && password) {
|
||||||
String auth = user;
|
String auth = user;
|
||||||
auth += ":";
|
auth += ":";
|
||||||
@ -395,7 +358,7 @@ void WebSocketsServer::setAuthorization(const char * user, const char * password
|
|||||||
* set the Authorizatio for the http request
|
* set the Authorizatio for the http request
|
||||||
* @param auth const char * base64
|
* @param auth const char * base64
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::setAuthorization(const char * auth) {
|
void WebSocketsServerCore::setAuthorization(const char * auth) {
|
||||||
if(auth) {
|
if(auth) {
|
||||||
_base64Authorization = auth;
|
_base64Authorization = auth;
|
||||||
}
|
}
|
||||||
@ -405,7 +368,7 @@ void WebSocketsServer::setAuthorization(const char * auth) {
|
|||||||
* count the connected clients (optional ping them)
|
* count the connected clients (optional ping them)
|
||||||
* @param ping bool ping the connected clients
|
* @param ping bool ping the connected clients
|
||||||
*/
|
*/
|
||||||
int WebSocketsServer::connectedClients(bool ping) {
|
int WebSocketsServerCore::connectedClients(bool ping) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
@ -423,7 +386,7 @@ int WebSocketsServer::connectedClients(bool ping) {
|
|||||||
* see if one client is connected
|
* see if one client is connected
|
||||||
* @param num uint8_t client id
|
* @param num uint8_t client id
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::clientIsConnected(uint8_t num) {
|
bool WebSocketsServerCore::clientIsConnected(uint8_t num) {
|
||||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -437,7 +400,7 @@ bool WebSocketsServer::clientIsConnected(uint8_t num) {
|
|||||||
* @param num uint8_t client id
|
* @param num uint8_t client id
|
||||||
* @return IPAddress
|
* @return IPAddress
|
||||||
*/
|
*/
|
||||||
IPAddress WebSocketsServer::remoteIP(uint8_t num) {
|
IPAddress WebSocketsServerCore::remoteIP(uint8_t num) {
|
||||||
if(num < WEBSOCKETS_SERVER_CLIENT_MAX) {
|
if(num < WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||||
WSclient_t * client = &_clients[num];
|
WSclient_t * client = &_clients[num];
|
||||||
if(clientIsConnected(client)) {
|
if(clientIsConnected(client)) {
|
||||||
@ -457,7 +420,7 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) {
|
|||||||
* handle new client connection
|
* handle new client connection
|
||||||
* @param client
|
* @param client
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
// search free list entry for client
|
// search free list entry for client
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
@ -486,7 +449,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||||
client->tcp->onDisconnect(std::bind([](WebSocketsServer * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool {
|
client->tcp->onDisconnect(std::bind([](WebSocketsServerCore * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool {
|
||||||
DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num);
|
DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num);
|
||||||
|
|
||||||
AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp;
|
AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp;
|
||||||
@ -498,7 +461,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
|||||||
},
|
},
|
||||||
this, std::placeholders::_1, client));
|
this, std::placeholders::_1, client));
|
||||||
|
|
||||||
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine)));
|
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServerCore::handleHeader, this, client, &(client->cHttpLine)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
client->pingInterval = _pingInterval;
|
client->pingInterval = _pingInterval;
|
||||||
@ -507,11 +470,11 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
|||||||
client->lastPing = millis();
|
client->lastPing = millis();
|
||||||
client->pongReceived = false;
|
client->pongReceived = false;
|
||||||
|
|
||||||
return true;
|
return client;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -521,7 +484,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
|||||||
* @param payload uint8_t *
|
* @param payload uint8_t *
|
||||||
* @param length size_t
|
* @param length size_t
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) {
|
void WebSocketsServerCore::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) {
|
||||||
WStype_t type = WStype_ERROR;
|
WStype_t type = WStype_ERROR;
|
||||||
|
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
@ -549,22 +512,10 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect an client
|
* Discard a native client
|
||||||
* @param client WSclient_t * ptr to the client struct
|
* @param client WSclient_t * ptr to the client struct contaning the native client "->tcp"
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
void WebSocketsServerCore::dropNativeClient(WSclient_t * client) {
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
|
||||||
if(client->isSSL && client->ssl) {
|
|
||||||
if(client->ssl->connected()) {
|
|
||||||
client->ssl->flush();
|
|
||||||
client->ssl->stop();
|
|
||||||
}
|
|
||||||
delete client->ssl;
|
|
||||||
client->ssl = NULL;
|
|
||||||
client->tcp = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(client->tcp) {
|
if(client->tcp) {
|
||||||
if(client->tcp->connected()) {
|
if(client->tcp->connected()) {
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32)
|
||||||
@ -579,6 +530,26 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
|||||||
#endif
|
#endif
|
||||||
client->tcp = NULL;
|
client->tcp = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect an client
|
||||||
|
* @param client WSclient_t * ptr to the client struct
|
||||||
|
*/
|
||||||
|
void WebSocketsServerCore::clientDisconnect(WSclient_t * client) {
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||||
|
if(client->isSSL && client->ssl) {
|
||||||
|
if(client->ssl->connected()) {
|
||||||
|
client->ssl->flush();
|
||||||
|
client->ssl->stop();
|
||||||
|
}
|
||||||
|
delete client->ssl;
|
||||||
|
client->ssl = NULL;
|
||||||
|
client->tcp = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dropNativeClient(client);
|
||||||
|
|
||||||
client->cUrl = "";
|
client->cUrl = "";
|
||||||
client->cKey = "";
|
client->cKey = "";
|
||||||
@ -605,7 +576,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
|||||||
* @param client WSclient_t * ptr to the client struct
|
* @param client WSclient_t * ptr to the client struct
|
||||||
* @return true = connected
|
* @return true = connected
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
|
bool WebSocketsServerCore::clientIsConnected(WSclient_t * client) {
|
||||||
if(!client->tcp) {
|
if(!client->tcp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -632,6 +603,30 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
|
/**
|
||||||
|
* Handle incoming Connection Request
|
||||||
|
*/
|
||||||
|
WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient) {
|
||||||
|
WSclient_t * client = newClient(tcpClient);
|
||||||
|
|
||||||
|
if(!client) {
|
||||||
|
// no free space to handle client
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||||
|
#ifndef NODEBUG_WEBSOCKETS
|
||||||
|
IPAddress ip = tcpClient->remoteIP();
|
||||||
|
#endif
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
#else
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n");
|
||||||
|
#endif
|
||||||
|
dropNativeClient(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
WEBSOCKETS_YIELD();
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle incoming Connection Request
|
* Handle incoming Connection Request
|
||||||
*/
|
*/
|
||||||
@ -639,36 +634,16 @@ void WebSocketsServer::handleNewClients(void) {
|
|||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||||
while(_server->hasClient()) {
|
while(_server->hasClient()) {
|
||||||
#endif
|
#endif
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
|
||||||
// store new connection
|
// store new connection
|
||||||
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
||||||
#else
|
|
||||||
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!tcpClient) {
|
if(!tcpClient) {
|
||||||
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!");
|
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = newClient(tcpClient);
|
handleNewClient(tcpClient);
|
||||||
|
|
||||||
if(!ok) {
|
|
||||||
// no free space to handle client
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
|
||||||
#ifndef NODEBUG_WEBSOCKETS
|
|
||||||
IPAddress ip = tcpClient->remoteIP();
|
|
||||||
#endif
|
|
||||||
DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
|
||||||
#else
|
|
||||||
DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n");
|
|
||||||
#endif
|
|
||||||
tcpClient->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
WEBSOCKETS_YIELD();
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -677,7 +652,7 @@ void WebSocketsServer::handleNewClients(void) {
|
|||||||
/**
|
/**
|
||||||
* Handel incomming data from Client
|
* Handel incomming data from Client
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::handleClientData(void) {
|
void WebSocketsServerCore::handleClientData(void) {
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||||
client = &_clients[i];
|
client = &_clients[i];
|
||||||
@ -712,7 +687,7 @@ void WebSocketsServer::handleClientData(void) {
|
|||||||
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
|
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
|
||||||
* @param headerName String ///< the name of the header being checked
|
* @param headerName String ///< the name of the header being checked
|
||||||
*/
|
*/
|
||||||
bool WebSocketsServer::hasMandatoryHeader(String headerName) {
|
bool WebSocketsServerCore::hasMandatoryHeader(String headerName) {
|
||||||
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
|
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
|
||||||
if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName))
|
if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName))
|
||||||
return true;
|
return true;
|
||||||
@ -725,7 +700,7 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) {
|
|||||||
* @param client WSclient_t * ///< pointer to the client struct
|
* @param client WSclient_t * ///< pointer to the client struct
|
||||||
* @param headerLine String ///< the header being read / processed
|
* @param headerLine String ///< the header being read / processed
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine) {
|
||||||
static const char * NEW_LINE = "\r\n";
|
static const char * NEW_LINE = "\r\n";
|
||||||
|
|
||||||
headerLine->trim(); // remove \r
|
headerLine->trim(); // remove \r
|
||||||
@ -784,7 +759,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
|||||||
|
|
||||||
(*headerLine) = "";
|
(*headerLine) = "";
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||||
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine)));
|
client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServerCore::handleHeader, this, client, &(client->cHttpLine)));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num);
|
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num);
|
||||||
@ -881,7 +856,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
|||||||
/**
|
/**
|
||||||
* send heartbeat ping to server in set intervals
|
* send heartbeat ping to server in set intervals
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::handleHBPing(WSclient_t * client) {
|
void WebSocketsServerCore::handleHBPing(WSclient_t * client) {
|
||||||
if(client->pingInterval == 0)
|
if(client->pingInterval == 0)
|
||||||
return;
|
return;
|
||||||
uint32_t pi = millis() - client->lastPing;
|
uint32_t pi = millis() - client->lastPing;
|
||||||
@ -900,7 +875,7 @@ void WebSocketsServer::handleHBPing(WSclient_t * client) {
|
|||||||
* @param pongTimeout uint32_t millis after which pong should timout if not received
|
* @param pongTimeout uint32_t millis after which pong should timout if not received
|
||||||
* @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect
|
* @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) {
|
void WebSocketsServerCore::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) {
|
||||||
_pingInterval = pingInterval;
|
_pingInterval = pingInterval;
|
||||||
_pongTimeout = pongTimeout;
|
_pongTimeout = pongTimeout;
|
||||||
_disconnectTimeoutCount = disconnectTimeoutCount;
|
_disconnectTimeoutCount = disconnectTimeoutCount;
|
||||||
@ -915,7 +890,7 @@ void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeo
|
|||||||
/**
|
/**
|
||||||
* disable ping/pong heartbeat process
|
* disable ping/pong heartbeat process
|
||||||
*/
|
*/
|
||||||
void WebSocketsServer::disableHeartbeat() {
|
void WebSocketsServerCore::disableHeartbeat() {
|
||||||
_pingInterval = 0;
|
_pingInterval = 0;
|
||||||
|
|
||||||
WSclient_t * client;
|
WSclient_t * client;
|
||||||
@ -923,4 +898,51 @@ void WebSocketsServer::disableHeartbeat() {
|
|||||||
client = &_clients[i];
|
client = &_clients[i];
|
||||||
client->pingInterval = 0;
|
client->pingInterval = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// WebSocketServer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called to initialize the Websocket server
|
||||||
|
*/
|
||||||
|
void WebSocketsServer::begin(void) {
|
||||||
|
WebSocketsServerCore::begin();
|
||||||
|
_server->begin();
|
||||||
|
|
||||||
|
DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocketsServer::close(void) {
|
||||||
|
WebSocketsServerCore::close();
|
||||||
|
#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 WebSocketsServerCore::loop(void) {
|
||||||
|
if(_runnning) {
|
||||||
|
WEBSOCKETS_YIELD();
|
||||||
|
handleClientData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called in arduino loop
|
||||||
|
*/
|
||||||
|
void WebSocketsServer::loop(void) {
|
||||||
|
if(_runnning) {
|
||||||
|
WEBSOCKETS_YIELD();
|
||||||
|
handleNewClients();
|
||||||
|
WebSocketsServerCore::loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -31,8 +31,14 @@
|
|||||||
#define WEBSOCKETS_SERVER_CLIENT_MAX (5)
|
#define WEBSOCKETS_SERVER_CLIENT_MAX (5)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class WebSocketsServer : protected WebSockets {
|
class WebSocketsServerCore : protected WebSockets {
|
||||||
public:
|
public:
|
||||||
|
WebSocketsServerCore(const String & origin = "", const String & protocol = "arduino");
|
||||||
|
virtual ~WebSocketsServerCore(void);
|
||||||
|
|
||||||
|
void begin(void);
|
||||||
|
void close(void);
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
|
typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
|
||||||
typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue);
|
typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue);
|
||||||
@ -41,19 +47,6 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
typedef std::function<bool(String headerName, String headerValue)> WebSocketServerHttpHeaderValFunc;
|
typedef std::function<bool(String headerName, String headerValue)> WebSocketServerHttpHeaderValFunc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino");
|
|
||||||
virtual ~WebSocketsServer(void);
|
|
||||||
|
|
||||||
void begin(void);
|
|
||||||
void close(void);
|
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
|
||||||
void loop(void);
|
|
||||||
#else
|
|
||||||
// Async interface not need a loop call
|
|
||||||
void loop(void) __attribute__((deprecated)) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void onEvent(WebSocketServerEvent cbEvent);
|
void onEvent(WebSocketServerEvent cbEvent);
|
||||||
void onValidateHttpHeader(
|
void onValidateHttpHeader(
|
||||||
WebSocketServerHttpHeaderValFunc validationFunc,
|
WebSocketServerHttpHeaderValFunc validationFunc,
|
||||||
@ -93,7 +86,7 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
int connectedClients(bool ping = false);
|
int connectedClients(bool ping = false);
|
||||||
|
|
||||||
bool clientIsConnected(uint8_t num);
|
bool clientIsConnected(uint8_t num);
|
||||||
|
|
||||||
void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);
|
void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);
|
||||||
void disableHeartbeat();
|
void disableHeartbeat();
|
||||||
|
|
||||||
@ -101,16 +94,19 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
IPAddress remoteIP(uint8_t num);
|
IPAddress remoteIP(uint8_t num);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
|
void loop(void); // handle client data only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t _port;
|
|
||||||
String _origin;
|
String _origin;
|
||||||
String _protocol;
|
String _protocol;
|
||||||
String _base64Authorization; ///< Base64 encoded Auth request
|
String _base64Authorization; ///< Base64 encoded Auth request
|
||||||
String * _mandatoryHttpHeaders;
|
String * _mandatoryHttpHeaders;
|
||||||
size_t _mandatoryHttpHeaderCount;
|
size_t _mandatoryHttpHeaderCount;
|
||||||
|
|
||||||
WEBSOCKETS_NETWORK_SERVER_CLASS * _server;
|
|
||||||
|
|
||||||
WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
|
WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
|
||||||
|
|
||||||
WebSocketServerEvent _cbEvent;
|
WebSocketServerEvent _cbEvent;
|
||||||
@ -122,15 +118,12 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
uint32_t _pongTimeout;
|
uint32_t _pongTimeout;
|
||||||
uint8_t _disconnectTimeoutCount;
|
uint8_t _disconnectTimeoutCount;
|
||||||
|
|
||||||
bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
|
|
||||||
|
|
||||||
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
||||||
|
|
||||||
void clientDisconnect(WSclient_t * client);
|
void clientDisconnect(WSclient_t * client);
|
||||||
bool clientIsConnected(WSclient_t * client);
|
bool clientIsConnected(WSclient_t * client);
|
||||||
|
|
||||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
void handleNewClients(void);
|
|
||||||
void handleClientData(void);
|
void handleClientData(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -206,6 +199,15 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
|
WSclient_t * handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drop native tcp connection (client->tcp)
|
||||||
|
*/
|
||||||
|
void dropNativeClient(WSclient_t * client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
|
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
|
||||||
@ -214,4 +216,28 @@ class WebSocketsServer : protected WebSockets {
|
|||||||
bool hasMandatoryHeader(String headerName);
|
bool hasMandatoryHeader(String headerName);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WebSocketsServer : public WebSocketsServerCore {
|
||||||
|
public:
|
||||||
|
WebSocketsServer(uint16_t port, const String & origin = "", const String & protocol = "arduino");
|
||||||
|
virtual ~WebSocketsServer(void);
|
||||||
|
|
||||||
|
void begin(void);
|
||||||
|
void close(void);
|
||||||
|
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
|
void loop(void); // handle incoming client and client data
|
||||||
|
#else
|
||||||
|
// Async interface not need a loop call
|
||||||
|
void loop(void) __attribute__((deprecated)) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||||
|
void handleNewClients(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint16_t _port;
|
||||||
|
WEBSOCKETS_NETWORK_SERVER_CLASS * _server;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* WEBSOCKETSSERVER_H_ */
|
#endif /* WEBSOCKETSSERVER_H_ */
|
||||||
|
36
src/WebSocketsVersion.h
Normal file
36
src/WebSocketsVersion.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @file WebSocketsVersion.h
|
||||||
|
* @date 09.02.2021
|
||||||
|
* @author Markus Sattler
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||||
|
* This file is part of the WebSockets for Arduino.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBSOCKETSVERSION_H_
|
||||||
|
#define WEBSOCKETSVERSION_H_
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION "2.3.5"
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION_MAJOR 2
|
||||||
|
#define WEBSOCKETS_VERSION_MINOR 3
|
||||||
|
#define WEBSOCKETS_VERSION_PATCH 5
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION_INT 2003005
|
||||||
|
|
||||||
|
#endif /* WEBSOCKETSVERSION_H_ */
|
@ -27,6 +27,64 @@ function build_sketches()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function build_sketch()
|
||||||
|
{
|
||||||
|
local arduino=$1
|
||||||
|
local sketch=$2
|
||||||
|
$arduino --verify $sketch;
|
||||||
|
local result=$?
|
||||||
|
if [ $result -ne 0 ]; then
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_sketches_json()
|
||||||
|
{
|
||||||
|
local arduino=$1
|
||||||
|
local srcpath=$2
|
||||||
|
local platform=$3
|
||||||
|
local sketches=($(find $srcpath -name *.ino))
|
||||||
|
echo -en "["
|
||||||
|
for sketch in "${sketches[@]}" ; do
|
||||||
|
local sketchdir=$(dirname $sketch)
|
||||||
|
if [[ -f "$sketchdir/.$platform.skip" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo -en "\"$sketch\""
|
||||||
|
if [[ $sketch != ${sketches[-1]} ]] ; then
|
||||||
|
echo -en ","
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
echo -en "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_sketches_json_matrix()
|
||||||
|
{
|
||||||
|
local arduino=$1
|
||||||
|
local srcpath=$2
|
||||||
|
local platform=$3
|
||||||
|
local ideversion=$4
|
||||||
|
local board=$5
|
||||||
|
local sketches=($(find $srcpath -name *.ino))
|
||||||
|
for sketch in "${sketches[@]}" ; do
|
||||||
|
local sketchdir=$(dirname $sketch)
|
||||||
|
local sketchname=$(basename $sketch)
|
||||||
|
if [[ -f "$sketchdir/.$platform.skip" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"ideversion\":\"$ideversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}"
|
||||||
|
if [[ $sketch != ${sketches[-1]} ]] ; then
|
||||||
|
echo -en ","
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
function get_core()
|
function get_core()
|
||||||
{
|
{
|
||||||
@ -37,17 +95,37 @@ function get_core()
|
|||||||
if [ "$1" = "esp8266" ] ; then
|
if [ "$1" = "esp8266" ] ; then
|
||||||
mkdir esp8266com
|
mkdir esp8266com
|
||||||
cd esp8266com
|
cd esp8266com
|
||||||
git clone https://github.com/esp8266/Arduino.git esp8266
|
git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266
|
||||||
cd esp8266/tools
|
cd esp8266/
|
||||||
|
rm -rf .git
|
||||||
|
cd tools
|
||||||
python get.py
|
python get.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" = "esp32" ] ; then
|
if [ "$1" = "esp32" ] ; then
|
||||||
mkdir espressif
|
mkdir espressif
|
||||||
cd espressif
|
cd espressif
|
||||||
git clone https://github.com/espressif/arduino-esp32.git esp32
|
git clone --depth 1 https://github.com/espressif/arduino-esp32.git esp32
|
||||||
cd esp32/tools
|
cd esp32/
|
||||||
|
rm -rf .git
|
||||||
|
cd tools
|
||||||
python get.py
|
python get.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clone_library() {
|
||||||
|
local url=$1
|
||||||
|
echo clone $(basename $url)
|
||||||
|
mkdir -p $HOME/Arduino/libraries
|
||||||
|
cd $HOME/Arduino/libraries
|
||||||
|
git clone --depth 1 $url
|
||||||
|
rm -rf */.git
|
||||||
|
rm -rf */.github
|
||||||
|
rm -rf */examples
|
||||||
|
}
|
||||||
|
|
||||||
|
function hash_library_names() {
|
||||||
|
cd $HOME/Arduino/libraries
|
||||||
|
ls | sha1sum -z | cut -c1-5
|
||||||
|
}
|
132
travis/version.py
Executable file
132
travis/version.py
Executable file
@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
import configparser
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
travis_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
base_dir = os.path.abspath(travis_dir + "/../")
|
||||||
|
|
||||||
|
def write_header_file(version):
|
||||||
|
hvs = version.split('.')
|
||||||
|
intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2])
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
text = f'''/**
|
||||||
|
* @file WebSocketsVersion.h
|
||||||
|
* @date {now.strftime("%d.%m.%Y")}
|
||||||
|
* @author Markus Sattler
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||||
|
* This file is part of the WebSockets for Arduino.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBSOCKETSVERSION_H_
|
||||||
|
#define WEBSOCKETSVERSION_H_
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION "{version}"
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION_MAJOR {hvs[0]}
|
||||||
|
#define WEBSOCKETS_VERSION_MINOR {hvs[1]}
|
||||||
|
#define WEBSOCKETS_VERSION_PATCH {hvs[2]}
|
||||||
|
|
||||||
|
#define WEBSOCKETS_VERSION_INT {intversion}
|
||||||
|
|
||||||
|
#endif /* WEBSOCKETSVERSION_H_ */
|
||||||
|
'''
|
||||||
|
with open(f'{base_dir}/src/WebSocketsVersion.h', 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
|
def get_library_properties_version():
|
||||||
|
library_properties = {}
|
||||||
|
with open(f'{base_dir}/library.properties', 'r') as f:
|
||||||
|
library_properties = configparser.ConfigParser()
|
||||||
|
library_properties.read_string('[root]\n' + f.read())
|
||||||
|
return library_properties['root']['version']
|
||||||
|
|
||||||
|
|
||||||
|
def get_library_json_version():
|
||||||
|
library_json = {}
|
||||||
|
with open(f'{base_dir}/library.json', 'r') as f:
|
||||||
|
library_json = json.load(f)
|
||||||
|
return library_json['version']
|
||||||
|
|
||||||
|
|
||||||
|
def get_header_versions():
|
||||||
|
data = {}
|
||||||
|
define = re.compile('^#define WEBSOCKETS_VERSION_?(.*) "?([0-9\.]*)"?$')
|
||||||
|
with open(f'{base_dir}/src/WebSocketsVersion.h', 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
m = define.match(line)
|
||||||
|
if m:
|
||||||
|
name = m[1]
|
||||||
|
if name == "":
|
||||||
|
name = "VERSION"
|
||||||
|
data[name] = m[2]
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Checks and update Version files')
|
||||||
|
parser.add_argument(
|
||||||
|
'--update', action='store_true', default=False)
|
||||||
|
parser.add_argument(
|
||||||
|
'--check', action='store_true', default=True)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.update:
|
||||||
|
library_properties_version = get_library_properties_version()
|
||||||
|
|
||||||
|
with open(f'{base_dir}/library.json', 'r') as f:
|
||||||
|
library_json = json.load(f)
|
||||||
|
|
||||||
|
library_json['version'] = library_properties_version
|
||||||
|
|
||||||
|
with open(f'{base_dir}/library.json', 'w') as f:
|
||||||
|
json.dump(library_json, f, indent=4, sort_keys=True)
|
||||||
|
|
||||||
|
write_header_file(library_properties_version)
|
||||||
|
|
||||||
|
|
||||||
|
library_json_version = get_library_json_version()
|
||||||
|
library_properties_version = get_library_properties_version()
|
||||||
|
header_version = get_header_versions()
|
||||||
|
|
||||||
|
print("WebSocketsVersion.h", header_version)
|
||||||
|
print(f"library.json: {library_json_version}")
|
||||||
|
print(f"library.properties: {library_properties_version}")
|
||||||
|
|
||||||
|
if args.check:
|
||||||
|
if library_json_version != library_properties_version or header_version['VERSION'] != library_properties_version:
|
||||||
|
raise Exception('versions did not match!')
|
||||||
|
|
||||||
|
hvs = header_version['VERSION'].split('.')
|
||||||
|
if header_version['MAJOR'] != hvs[0]:
|
||||||
|
raise Exception('header MAJOR version wrong!')
|
||||||
|
if header_version['MINOR'] != hvs[1]:
|
||||||
|
raise Exception('header MINOR version wrong!')
|
||||||
|
if header_version['PATCH'] != hvs[2]:
|
||||||
|
raise Exception('header PATCH version wrong!')
|
||||||
|
|
||||||
|
intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2])
|
||||||
|
if int(header_version['INT']) != intversion:
|
||||||
|
raise Exception('header INT version wrong!')
|
Reference in New Issue
Block a user