Skip to content

Commit 3a3d1c6

Browse files
authored
added ArduinoWiFiServer with send-to-all-clients functionality (#7612)
and with available() working according to Arduino documentation plus PagerServer example
1 parent 4436e32 commit 3a3d1c6

File tree

2 files changed

+207
-0
lines changed

2 files changed

+207
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Pager Server
3+
4+
The ESP8266WiFi library's WiFiServer and WiFiServerSecure
5+
work differently then WiFiServer and EthernetSever
6+
in Arduino networking libraries.
7+
This example demonstrates the ArduinoWiFiServer,
8+
which enhances the WiFiServer.
9+
ArduinoWiFiServer has available() behaving as documented
10+
and supports send-to-all-clients functionality, which
11+
is not implemented in ESP8266WiFi library's WiFiServer
12+
and WiFiServerSecure.
13+
14+
The example is a simple server that echoes any incoming
15+
messages to all connected clients. Connect two or more
16+
telnet sessions to see how server.available() and
17+
server.print() work.
18+
19+
created in September 2020 for ESP8266WiFi library
20+
by Juraj Andrassy https://github.com./jandrassy
21+
*/
22+
23+
#include <ESP8266WiFi.h>
24+
#include <ArduinoWiFiServer.h>
25+
26+
#ifndef STASSID
27+
#define STASSID "your-ssid"
28+
#define STAPSK "your-password"
29+
#endif
30+
31+
const char* ssid = STASSID;
32+
const char* password = STAPSK;
33+
34+
ArduinoWiFiServer server(2323);
35+
36+
void setup() {
37+
38+
Serial.begin(115200);
39+
40+
Serial.println();
41+
Serial.print("Connecting to ");
42+
Serial.println(ssid);
43+
44+
WiFi.begin(ssid, password);
45+
46+
while (WiFi.status() != WL_CONNECTED) {
47+
delay(500);
48+
Serial.print(".");
49+
}
50+
51+
server.begin();
52+
53+
IPAddress ip = WiFi.localIP();
54+
Serial.println();
55+
Serial.println("Connected to WiFi network.");
56+
Serial.print("To access the server, connect with Telnet client to ");
57+
Serial.print(ip);
58+
Serial.println(" 2323");
59+
}
60+
61+
void loop() {
62+
63+
WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client
64+
if (client) { // client is true only if it is connected and has data to read
65+
String s = client.readStringUntil('\n'); // read the message incoming from one of the clients
66+
s.trim(); // trim eventual \r
67+
Serial.println(s); // print the message to Serial Monitor
68+
client.print("echo: "); // this is only for the sending client
69+
server.println(s); // send the message to all connected clients
70+
server.flush(); // flush the buffers
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
ArduinoWiFiServer.h - Arduino compatible WiFiServer
3+
implementation for ESP8266Wifi library.
4+
Copyright (c) 2020 Juraj Andrassy
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#ifndef arduinowifiserver_h
22+
#define arduinowifiserver_h
23+
24+
#include <ESP8266WiFi.h>
25+
26+
#ifndef MAX_MONITORED_CLIENTS
27+
#define MAX_MONITORED_CLIENTS 5
28+
#endif
29+
30+
template <class TServer, class TClient>
31+
class ArduinoComptibleWiFiServerTemplate : public TServer {
32+
public:
33+
34+
ArduinoComptibleWiFiServerTemplate(const IPAddress& addr, uint16_t port) : TServer(addr, port) {}
35+
ArduinoComptibleWiFiServerTemplate(uint16_t port) : TServer(port) {}
36+
virtual ~ArduinoComptibleWiFiServerTemplate() {}
37+
38+
// https://www.arduino.cc/en/Reference/EthernetServerAccept
39+
TClient accept() {
40+
return TServer::available();
41+
}
42+
43+
// https://www.arduino.cc/en/Reference/WiFiServerAvailable
44+
TClient available() {
45+
46+
// update connected clients
47+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
48+
if (!connectedClients[i]) {
49+
connectedClients[i] = accept();
50+
}
51+
}
52+
// find next client with data available
53+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
54+
if (index == MAX_MONITORED_CLIENTS) {
55+
index = 0;
56+
}
57+
TClient& client = connectedClients[index];
58+
index++;
59+
if (client.available())
60+
return client;
61+
}
62+
return TClient(); // no client with data found
63+
}
64+
65+
virtual size_t write(uint8_t b) override {
66+
return write(&b, 1);
67+
}
68+
69+
virtual size_t write(const uint8_t *buf, size_t size) override {
70+
if (size == 0)
71+
return 0;
72+
size_t ret = 0;
73+
size_t a = size;
74+
while (true) {
75+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
76+
WiFiClient& client = connectedClients[i];
77+
if (client.status() == ESTABLISHED && client.availableForWrite() < (int) a) {
78+
a = client.availableForWrite();
79+
}
80+
}
81+
if (a == 0)
82+
break;
83+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
84+
if (connectedClients[i].status() == ESTABLISHED) {
85+
connectedClients[i].write(buf, a);
86+
}
87+
}
88+
ret += a;
89+
if (ret == size)
90+
break;
91+
buf += a;
92+
a = size - ret;
93+
}
94+
return ret;
95+
}
96+
97+
using Print::write;
98+
99+
virtual void flush() override {
100+
flush(0);
101+
}
102+
103+
virtual void flush(unsigned int maxWaitMs) {
104+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
105+
if (connectedClients[i].status() == ESTABLISHED) {
106+
connectedClients[i].flush(maxWaitMs);
107+
}
108+
}
109+
}
110+
111+
operator bool() {
112+
return (TServer::status() == LISTEN);
113+
}
114+
115+
void close() {
116+
TServer::stop();
117+
for (uint8_t i = 0; i < MAX_MONITORED_CLIENTS; i++) {
118+
if (connectedClients[i]) {
119+
connectedClients[i].stop();
120+
}
121+
}
122+
}
123+
void stop() {close();}
124+
void end() {close();}
125+
126+
private:
127+
TClient connectedClients[MAX_MONITORED_CLIENTS];
128+
uint8_t index = 0;
129+
130+
};
131+
132+
typedef ArduinoComptibleWiFiServerTemplate<WiFiServer, WiFiClient> ArduinoWiFiServer;
133+
typedef ArduinoComptibleWiFiServerTemplate<WiFiServerSecure, WiFiClientSecure> ArduinoWiFiServerSecure;
134+
135+
#endif

0 commit comments

Comments
 (0)