mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-06-25 15:01:36 +02:00
Compare commits
8 Commits
2.3.0
...
esp8266_sh
Author | SHA1 | Date | |
---|---|---|---|
4f52a0f38e | |||
f20fbbfcd9 | |||
28cd929e7e | |||
826c6b423a | |||
7fea0b8bdf | |||
4db14451fb | |||
80bf087cd0 | |||
5caff59f7f |
@ -90,6 +90,10 @@ void setup() {
|
||||
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.onEvent(webSocketEvent);
|
||||
}
|
||||
|
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()
|
@ -13,7 +13,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Links2004/arduinoWebSockets.git"
|
||||
},
|
||||
"version": "2.3.0",
|
||||
"version": "2.3.1",
|
||||
"license": "LGPL-2.1",
|
||||
"export": {
|
||||
"exclude": [
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=WebSockets
|
||||
version=2.3.0
|
||||
version=2.3.1
|
||||
author=Markus Sattler
|
||||
maintainer=Markus Sattler
|
||||
sentence=WebSockets for Arduino (Server + Client)
|
||||
|
@ -24,7 +24,37 @@ void SocketIOclient::begin(String host, uint16_t port, String url, String protoc
|
||||
WebSocketsClient::beginSocketIO(host, port, url, protocol);
|
||||
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#if !defined(SSL_AXTLS)
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
/**
|
||||
* set callback function
|
||||
* @param cbEvent SocketIOclientEvent
|
||||
|
@ -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(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);
|
||||
|
||||
void onEvent(SocketIOclientEvent cbEvent);
|
||||
|
@ -644,7 +644,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
|
||||
} else {
|
||||
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
|
||||
}
|
||||
if (n > 0) {
|
||||
if(n > 0) {
|
||||
WEBSOCKETS_YIELD();
|
||||
}
|
||||
}
|
||||
@ -698,7 +698,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) {
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
|
||||
}
|
||||
if (n > 0) {
|
||||
if(n > 0) {
|
||||
WEBSOCKETS_YIELD();
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,11 @@
|
||||
|
||||
#ifndef NODEBUG_WEBSOCKETS
|
||||
#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
|
||||
//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ )
|
||||
#endif
|
||||
|
71
src/WebSockets4WebServer.h
Normal file
71
src/WebSockets4WebServer.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @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) {
|
||||
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;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK
|
||||
|
||||
#endif // __WEBSOCKETS4WEBSERVER_H
|
@ -122,12 +122,6 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u
|
||||
_fingerprint = fingerprint;
|
||||
_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) {
|
||||
begin(host, port, url, protocol);
|
||||
@ -135,6 +129,20 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch
|
||||
_fingerprint = SSL_FINGERPRINT_NULL;
|
||||
_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 // HAS_SSL
|
||||
|
||||
@ -159,17 +167,28 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url,
|
||||
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) {
|
||||
begin(host, port, url, protocol);
|
||||
_client.isSocketIO = true;
|
||||
_client.isSSL = true;
|
||||
_fingerprint = SSL_FINGERPRINT_NULL;
|
||||
#if defined(SSL_AXTLS)
|
||||
_CA_cert = CA_cert;
|
||||
#else
|
||||
#if defined(SSL_BARESSL)
|
||||
_CA_cert = new BearSSL::X509List(CA_cert);
|
||||
#else
|
||||
_CA_cert = CA_cert;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
@ -213,6 +232,10 @@ void WebSocketsClient::loop(void) {
|
||||
_client.ssl->setFingerprint(_fingerprint);
|
||||
} else {
|
||||
_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
|
||||
}
|
||||
} else {
|
||||
@ -613,7 +636,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
|
||||
}
|
||||
|
||||
// add extra headers; by default this includes "Origin: file://"
|
||||
if(client->extraHeaders) {
|
||||
if(client->extraHeaders.length() > 0) {
|
||||
handshake += client->extraHeaders + NEW_LINE;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,8 @@ class WebSocketsClient : protected WebSockets {
|
||||
#else
|
||||
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 setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL);
|
||||
void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL);
|
||||
#endif
|
||||
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino");
|
||||
#endif
|
||||
@ -59,7 +61,11 @@ class WebSocketsClient : protected WebSockets {
|
||||
#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(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");
|
||||
#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
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
@ -110,6 +116,8 @@ class WebSocketsClient : protected WebSockets {
|
||||
#else
|
||||
const uint8_t * _fingerprint;
|
||||
BearSSL::X509List * _CA_cert;
|
||||
BearSSL::X509List * _client_cert;
|
||||
BearSSL::PrivateKey * _client_key;
|
||||
#define SSL_FINGERPRINT_NULL NULL
|
||||
#endif
|
||||
|
||||
|
@ -25,8 +25,7 @@
|
||||
#include "WebSockets.h"
|
||||
#include "WebSocketsServer.h"
|
||||
|
||||
WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) {
|
||||
_port = port;
|
||||
WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) {
|
||||
_origin = origin;
|
||||
_protocol = protocol;
|
||||
_runnning = false;
|
||||
@ -34,15 +33,6 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
|
||||
_pongTimeout = 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;
|
||||
|
||||
_httpHeaderValidationFunc = NULL;
|
||||
@ -52,7 +42,21 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol
|
||||
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
|
||||
close();
|
||||
|
||||
@ -62,10 +66,13 @@ WebSocketsServer::~WebSocketsServer() {
|
||||
_mandatoryHttpHeaderCount = 0;
|
||||
}
|
||||
|
||||
WebSocketsServer::~WebSocketsServer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* called to initialize the Websocket server
|
||||
*/
|
||||
void WebSocketsServer::begin(void) {
|
||||
void WebSocketsServerCore::begin(void) {
|
||||
WSclient_t * client;
|
||||
|
||||
// init client storage
|
||||
@ -79,18 +86,27 @@ void WebSocketsServer::begin(void) {
|
||||
client->isSSL = false;
|
||||
client->ssl = NULL;
|
||||
#endif
|
||||
client->cUrl = "";
|
||||
client->cCode = 0;
|
||||
client->cKey = "";
|
||||
client->cProtocol = "";
|
||||
client->cVersion = 0;
|
||||
client->cUrl = "";
|
||||
client->cCode = 0;
|
||||
|
||||
client->cIsClient = false;
|
||||
client->cIsUpgrade = false;
|
||||
client->cIsWebsocket = false;
|
||||
|
||||
client->base64Authorization = "";
|
||||
client->cSessionId = "";
|
||||
client->cKey = "";
|
||||
client->cAccept = "";
|
||||
client->cProtocol = "";
|
||||
client->cExtensions = "";
|
||||
client->cVersion = 0;
|
||||
|
||||
client->cWsRXsize = 0;
|
||||
|
||||
client->base64Authorization = "";
|
||||
client->plainAuthorization = "";
|
||||
|
||||
client->extraHeaders = "";
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
client->cHttpLine = "";
|
||||
#endif
|
||||
@ -111,43 +127,18 @@ void WebSocketsServer::begin(void) {
|
||||
#endif
|
||||
|
||||
_runnning = true;
|
||||
_server->begin();
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n");
|
||||
}
|
||||
|
||||
void WebSocketsServer::close(void) {
|
||||
void WebSocketsServerCore::close(void) {
|
||||
_runnning = false;
|
||||
disconnect();
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
|
||||
_server->close();
|
||||
#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
|
||||
_server->end();
|
||||
#else
|
||||
// TODO how to close server?
|
||||
#endif
|
||||
}
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
/**
|
||||
* called in arduino loop
|
||||
*/
|
||||
void WebSocketsServer::loop(void) {
|
||||
if(_runnning) {
|
||||
WEBSOCKETS_YIELD();
|
||||
handleNewClients();
|
||||
WEBSOCKETS_YIELD();
|
||||
handleClientData();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* set callback function
|
||||
* @param cbEvent WebSocketServerEvent
|
||||
*/
|
||||
void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) {
|
||||
void WebSocketsServerCore::onEvent(WebSocketServerEvent cbEvent) {
|
||||
_cbEvent = cbEvent;
|
||||
}
|
||||
|
||||
@ -157,7 +148,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 mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array
|
||||
*/
|
||||
void WebSocketsServer::onValidateHttpHeader(
|
||||
void WebSocketsServerCore::onValidateHttpHeader(
|
||||
WebSocketServerHttpHeaderValFunc validationFunc,
|
||||
const char * mandatoryHttpHeaders[],
|
||||
size_t mandatoryHttpHeaderCount) {
|
||||
@ -182,7 +173,7 @@ void WebSocketsServer::onValidateHttpHeader(
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
* @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) {
|
||||
return false;
|
||||
}
|
||||
@ -196,19 +187,19 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -219,7 +210,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, String & payload) {
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
* @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;
|
||||
bool ret = true;
|
||||
if(length == 0) {
|
||||
@ -238,19 +229,19 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) {
|
||||
bool WebSocketsServerCore::broadcastTXT(const char * payload, size_t 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());
|
||||
}
|
||||
|
||||
@ -262,7 +253,7 @@ bool WebSocketsServer::broadcastTXT(String & payload) {
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
* @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) {
|
||||
return false;
|
||||
}
|
||||
@ -273,7 +264,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo
|
||||
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);
|
||||
}
|
||||
|
||||
@ -284,7 +275,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng
|
||||
* @param headerToPayload bool (see sendFrame for more details)
|
||||
* @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;
|
||||
bool ret = true;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
@ -299,7 +290,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade
|
||||
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);
|
||||
}
|
||||
|
||||
@ -310,7 +301,7 @@ bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) {
|
||||
* @param length size_t
|
||||
* @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) {
|
||||
return false;
|
||||
}
|
||||
@ -321,7 +312,7 @@ bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -331,7 +322,7 @@ bool WebSocketsServer::sendPing(uint8_t num, String & payload) {
|
||||
* @param length size_t
|
||||
* @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;
|
||||
bool ret = true;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
@ -346,14 +337,14 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WebSocketsServer::broadcastPing(String & payload) {
|
||||
bool WebSocketsServerCore::broadcastPing(String & payload) {
|
||||
return broadcastPing((uint8_t *)payload.c_str(), payload.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* disconnect all clients
|
||||
*/
|
||||
void WebSocketsServer::disconnect(void) {
|
||||
void WebSocketsServerCore::disconnect(void) {
|
||||
WSclient_t * client;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
client = &_clients[i];
|
||||
@ -367,7 +358,7 @@ void WebSocketsServer::disconnect(void) {
|
||||
* disconnect one client
|
||||
* @param num uint8_t client id
|
||||
*/
|
||||
void WebSocketsServer::disconnect(uint8_t num) {
|
||||
void WebSocketsServerCore::disconnect(uint8_t num) {
|
||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||
return;
|
||||
}
|
||||
@ -382,7 +373,7 @@ void WebSocketsServer::disconnect(uint8_t num) {
|
||||
* @param user 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) {
|
||||
String auth = user;
|
||||
auth += ":";
|
||||
@ -395,7 +386,7 @@ void WebSocketsServer::setAuthorization(const char * user, const char * password
|
||||
* set the Authorizatio for the http request
|
||||
* @param auth const char * base64
|
||||
*/
|
||||
void WebSocketsServer::setAuthorization(const char * auth) {
|
||||
void WebSocketsServerCore::setAuthorization(const char * auth) {
|
||||
if(auth) {
|
||||
_base64Authorization = auth;
|
||||
}
|
||||
@ -405,7 +396,7 @@ void WebSocketsServer::setAuthorization(const char * auth) {
|
||||
* count the connected clients (optional ping them)
|
||||
* @param ping bool ping the connected clients
|
||||
*/
|
||||
int WebSocketsServer::connectedClients(bool ping) {
|
||||
int WebSocketsServerCore::connectedClients(bool ping) {
|
||||
WSclient_t * client;
|
||||
int count = 0;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
@ -423,7 +414,7 @@ int WebSocketsServer::connectedClients(bool ping) {
|
||||
* see if one client is connected
|
||||
* @param num uint8_t client id
|
||||
*/
|
||||
bool WebSocketsServer::clientIsConnected(uint8_t num) {
|
||||
bool WebSocketsServerCore::clientIsConnected(uint8_t num) {
|
||||
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||
return false;
|
||||
}
|
||||
@ -437,7 +428,7 @@ bool WebSocketsServer::clientIsConnected(uint8_t num) {
|
||||
* @param num uint8_t client id
|
||||
* @return IPAddress
|
||||
*/
|
||||
IPAddress WebSocketsServer::remoteIP(uint8_t num) {
|
||||
IPAddress WebSocketsServerCore::remoteIP(uint8_t num) {
|
||||
if(num < WEBSOCKETS_SERVER_CLIENT_MAX) {
|
||||
WSclient_t * client = &_clients[num];
|
||||
if(clientIsConnected(client)) {
|
||||
@ -457,7 +448,7 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) {
|
||||
* handle new client connection
|
||||
* @param client
|
||||
*/
|
||||
bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
WSclient_t * client;
|
||||
// search free list entry for client
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
@ -486,7 +477,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
#endif
|
||||
|
||||
#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);
|
||||
|
||||
AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp;
|
||||
@ -498,7 +489,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
},
|
||||
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
|
||||
|
||||
client->pingInterval = _pingInterval;
|
||||
@ -507,11 +498,11 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
client->lastPing = millis();
|
||||
client->pongReceived = false;
|
||||
|
||||
return true;
|
||||
return client;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -521,7 +512,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) {
|
||||
* @param payload uint8_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;
|
||||
|
||||
switch(opcode) {
|
||||
@ -549,22 +540,10 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect an client
|
||||
* @param client WSclient_t * ptr to the client struct
|
||||
* Discard a native client
|
||||
* @param client WSclient_t * ptr to the client struct contaning the native client "->tcp"
|
||||
*/
|
||||
void WebSocketsServer::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
|
||||
|
||||
void WebSocketsServerCore::dropNativeClient(WSclient_t * client) {
|
||||
if(client->tcp) {
|
||||
if(client->tcp->connected()) {
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32)
|
||||
@ -579,6 +558,26 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
||||
#endif
|
||||
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->cKey = "";
|
||||
@ -605,7 +604,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) {
|
||||
* @param client WSclient_t * ptr to the client struct
|
||||
* @return true = connected
|
||||
*/
|
||||
bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
|
||||
bool WebSocketsServerCore::clientIsConnected(WSclient_t * client) {
|
||||
if(!client->tcp) {
|
||||
return false;
|
||||
}
|
||||
@ -632,6 +631,30 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) {
|
||||
return false;
|
||||
}
|
||||
#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
|
||||
*/
|
||||
@ -639,36 +662,16 @@ void WebSocketsServer::handleNewClients(void) {
|
||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
while(_server->hasClient()) {
|
||||
#endif
|
||||
bool ok = false;
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
|
||||
// store new connection
|
||||
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
||||
#else
|
||||
WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available());
|
||||
#endif
|
||||
|
||||
if(!tcpClient) {
|
||||
DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!");
|
||||
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)
|
||||
}
|
||||
#endif
|
||||
@ -677,7 +680,7 @@ void WebSocketsServer::handleNewClients(void) {
|
||||
/**
|
||||
* Handel incomming data from Client
|
||||
*/
|
||||
void WebSocketsServer::handleClientData(void) {
|
||||
void WebSocketsServerCore::handleClientData(void) {
|
||||
WSclient_t * client;
|
||||
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
|
||||
client = &_clients[i];
|
||||
@ -712,7 +715,7 @@ void WebSocketsServer::handleClientData(void) {
|
||||
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
|
||||
* @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++) {
|
||||
if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName))
|
||||
return true;
|
||||
@ -725,7 +728,7 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) {
|
||||
* @param client WSclient_t * ///< pointer to the client struct
|
||||
* @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";
|
||||
|
||||
headerLine->trim(); // remove \r
|
||||
@ -784,7 +787,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
|
||||
(*headerLine) = "";
|
||||
#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
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num);
|
||||
@ -881,7 +884,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
|
||||
/**
|
||||
* send heartbeat ping to server in set intervals
|
||||
*/
|
||||
void WebSocketsServer::handleHBPing(WSclient_t * client) {
|
||||
void WebSocketsServerCore::handleHBPing(WSclient_t * client) {
|
||||
if(client->pingInterval == 0)
|
||||
return;
|
||||
uint32_t pi = millis() - client->lastPing;
|
||||
@ -900,7 +903,7 @@ void WebSocketsServer::handleHBPing(WSclient_t * client) {
|
||||
* @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
|
||||
*/
|
||||
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;
|
||||
_pongTimeout = pongTimeout;
|
||||
_disconnectTimeoutCount = disconnectTimeoutCount;
|
||||
@ -915,7 +918,7 @@ void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeo
|
||||
/**
|
||||
* disable ping/pong heartbeat process
|
||||
*/
|
||||
void WebSocketsServer::disableHeartbeat() {
|
||||
void WebSocketsServerCore::disableHeartbeat() {
|
||||
_pingInterval = 0;
|
||||
|
||||
WSclient_t * client;
|
||||
@ -923,4 +926,51 @@ void WebSocketsServer::disableHeartbeat() {
|
||||
client = &_clients[i];
|
||||
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) {
|
||||
WebSocketsServer::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)
|
||||
#endif
|
||||
|
||||
class WebSocketsServer : protected WebSockets {
|
||||
class WebSocketsServerCore : protected WebSockets {
|
||||
public:
|
||||
WebSocketsServerCore(const String & origin = "", const String & protocol = "arduino");
|
||||
virtual ~WebSocketsServerCore(void);
|
||||
|
||||
void begin(void);
|
||||
void close(void);
|
||||
|
||||
#ifdef __AVR__
|
||||
typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
|
||||
typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue);
|
||||
@ -41,19 +47,6 @@ class WebSocketsServer : protected WebSockets {
|
||||
typedef std::function<bool(String headerName, String headerValue)> WebSocketServerHttpHeaderValFunc;
|
||||
#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 onValidateHttpHeader(
|
||||
WebSocketServerHttpHeaderValFunc validationFunc,
|
||||
@ -93,7 +86,7 @@ class WebSocketsServer : protected WebSockets {
|
||||
int connectedClients(bool ping = false);
|
||||
|
||||
bool clientIsConnected(uint8_t num);
|
||||
|
||||
|
||||
void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);
|
||||
void disableHeartbeat();
|
||||
|
||||
@ -101,16 +94,17 @@ class WebSocketsServer : protected WebSockets {
|
||||
IPAddress remoteIP(uint8_t num);
|
||||
#endif
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
void loop(void); // handle client data only
|
||||
#endif
|
||||
|
||||
protected:
|
||||
uint16_t _port;
|
||||
String _origin;
|
||||
String _protocol;
|
||||
String _base64Authorization; ///< Base64 encoded Auth request
|
||||
String * _mandatoryHttpHeaders;
|
||||
size_t _mandatoryHttpHeaderCount;
|
||||
|
||||
WEBSOCKETS_NETWORK_SERVER_CLASS * _server;
|
||||
|
||||
WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
|
||||
|
||||
WebSocketServerEvent _cbEvent;
|
||||
@ -122,7 +116,7 @@ class WebSocketsServer : protected WebSockets {
|
||||
uint32_t _pongTimeout;
|
||||
uint8_t _disconnectTimeoutCount;
|
||||
|
||||
bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
|
||||
WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
|
||||
|
||||
void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin);
|
||||
|
||||
@ -130,7 +124,6 @@ class WebSocketsServer : protected WebSockets {
|
||||
bool clientIsConnected(WSclient_t * client);
|
||||
|
||||
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
|
||||
void handleNewClients(void);
|
||||
void handleClientData(void);
|
||||
#endif
|
||||
|
||||
@ -206,6 +199,15 @@ class WebSocketsServer : protected WebSockets {
|
||||
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:
|
||||
/*
|
||||
* 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);
|
||||
};
|
||||
|
||||
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_ */
|
||||
|
Reference in New Issue
Block a user