diff --git a/libraries/ESP8266WiFi/examples/PagerServer/PagerServer.ino b/libraries/ESP8266WiFi/examples/PagerServer/PagerServer.ino new file mode 100644 index 0000000000..05fa597ab7 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/PagerServer/PagerServer.ino @@ -0,0 +1,72 @@ +/* + Pager Server + + The ESP8266WiFi library's WiFiServer and WiFiServerSecure + work differently then WiFiServer and EthernetSever + in Arduino networking libraries. + This example demonstrates the ArduinoWiFiServer, + which enhances the WiFiServer. + ArduinoWiFiServer has available() behaving as documented + and supports send-to-all-clients functionality, which + is not implemented in ESP8266WiFi library's WiFiServer + and WiFiServerSecure. + + The example is a simple server that echoes any incoming + messages to all connected clients. Connect two or more + telnet sessions to see how server.available() and + server.print() work. + + created in September 2020 for ESP8266WiFi library + by Juraj Andrassy https://github.com/jandrassy +*/ + +#include +#include + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +ArduinoWiFiServer server(2323); + +void setup() { + + Serial.begin(115200); + + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + server.begin(); + + IPAddress ip = WiFi.localIP(); + Serial.println(); + Serial.println("Connected to WiFi network."); + Serial.print("To access the server, connect with Telnet client to "); + Serial.print(ip); + Serial.println(" 2323"); +} + +void loop() { + + WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client + if (client) { // client is true only if it is connected and has data to read + String s = client.readStringUntil('\n'); // read the message incoming from one of the clients + s.trim(); // trim eventual \r + Serial.println(s); // print the message to Serial Monitor + client.print("echo: "); // this is only for the sending client + server.println(s); // send the message to all connected clients + server.flush(); // flush the buffers + } +} diff --git a/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h b/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h new file mode 100644 index 0000000000..31b8ea0c16 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ArduinoWiFiServer.h @@ -0,0 +1,135 @@ +/* + ArduinoWiFiServer.h - Arduino compatible WiFiServer + implementation for ESP8266Wifi library. + Copyright (c) 2020 Juraj Andrassy + + 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 arduinowifiserver_h +#define arduinowifiserver_h + +#include + +#ifndef MAX_MONITORED_CLIENTS +#define MAX_MONITORED_CLIENTS 5 +#endif + +template +class ArduinoComptibleWiFiServerTemplate : public TServer { +public: + + ArduinoComptibleWiFiServerTemplate(const IPAddress& addr, uint16_t port) : TServer(addr, port) {} + ArduinoComptibleWiFiServerTemplate(uint16_t port) : TServer(port) {} + virtual ~ArduinoComptibleWiFiServerTemplate() {} + + // https://www.arduino.cc/en/Reference/EthernetServerAccept + TClient accept() { + return TServer::available(); + } + + // https://www.arduino.cc/en/Reference/WiFiServerAvailable + TClient available() { + + // update connected clients + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + if (!connectedClients[i]) { + connectedClients[i] = accept(); + } + } + // find next client with data available + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + if (index == MAX_MONITORED_CLIENTS) { + index = 0; + } + TClient& client = connectedClients[index]; + index++; + if (client.available()) + return client; + } + return TClient(); // no client with data found + } + + virtual size_t write(uint8_t b) override { + return write(&b, 1); + } + + virtual size_t write(const uint8_t *buf, size_t size) override { + if (size == 0) + return 0; + size_t ret = 0; + size_t a = size; + while (true) { + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + WiFiClient& client = connectedClients[i]; + if (client.status() == ESTABLISHED && client.availableForWrite() < (int) a) { + a = client.availableForWrite(); + } + } + if (a == 0) + break; + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + if (connectedClients[i].status() == ESTABLISHED) { + connectedClients[i].write(buf, a); + } + } + ret += a; + if (ret == size) + break; + buf += a; + a = size - ret; + } + return ret; + } + + using Print::write; + + virtual void flush() override { + flush(0); + } + + virtual void flush(unsigned int maxWaitMs) { + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + if (connectedClients[i].status() == ESTABLISHED) { + connectedClients[i].flush(maxWaitMs); + } + } + } + + operator bool() { + return (TServer::status() == LISTEN); + } + + void close() { + TServer::stop(); + for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) { + if (connectedClients[i]) { + connectedClients[i].stop(); + } + } + } + void stop() {close();} + void end() {close();} + +private: + TClient connectedClients[MAX_MONITORED_CLIENTS]; + uint8_t index = 0; + +}; + +typedef ArduinoComptibleWiFiServerTemplate ArduinoWiFiServer; +typedef ArduinoComptibleWiFiServerTemplate ArduinoWiFiServerSecure; + +#endif