|
| 1 | +// SPDX-License-Identifier: LGPL-3.0-or-later |
| 2 | +// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov |
| 3 | + |
| 4 | +// |
| 5 | +// A simple WebChat room working over WebSockets |
| 6 | +// |
| 7 | + |
| 8 | +/* |
| 9 | + This example would show how WSocketServer could register connections/disconnections for every new user, |
| 10 | + deliver messages to all connected user and replicate incoming data amoung all members of chat room. |
| 11 | + Change you WiFi creds below, build and flash the code. |
| 12 | + Connect to console to monitor debug messages. |
| 13 | + Figure out IP of your board and access the board via web browser using two or more different devices, |
| 14 | + Chat with yourself, have fun :) |
| 15 | +*/ |
| 16 | + |
| 17 | +#include <AsyncWSocket.h> |
| 18 | +#include <WiFi.h> |
| 19 | +#include "html.h" |
| 20 | + |
| 21 | +#define WIFI_SSID "YourSSID" |
| 22 | +#define WIFI_PASSWD "YourPasswd" |
| 23 | + |
| 24 | +// WS Event server callback declaration |
| 25 | +void wsEvent(WSocketClient *client, WSocketClient::event_t event); |
| 26 | + |
| 27 | +// Our WebServer |
| 28 | +AsyncWebServer server(80); |
| 29 | +// WSocket Server URL and callback function |
| 30 | +WSocketServer ws("/chat", wsEvent); |
| 31 | + |
| 32 | +void wsEvent(WSocketClient *client, WSocketClient::event_t event){ |
| 33 | + switch (event){ |
| 34 | + // new client connected |
| 35 | + case WSocketClient::event_t::connect : { |
| 36 | + Serial.printf("Client id:%u connected\n", client->id); |
| 37 | + char buff[100]; |
| 38 | + snprintf(buff, 100, "WServer: Hello user, your id is:%u, there are %u members on-line, pls be polite here!", client->id, ws.activeClientsCount()); |
| 39 | + // greet new user personally |
| 40 | + ws.text(client->id, buff); |
| 41 | + snprintf(buff, 100, "WServer: New client with id:%u joined the room", client->id); |
| 42 | + // Announce new user entered the room |
| 43 | + ws.textAll(client->id, buff); |
| 44 | + break; |
| 45 | + } |
| 46 | + |
| 47 | + // client diconnected |
| 48 | + case WSocketClient::event_t::disconnect : { |
| 49 | + Serial.printf("Client id:%u disconnected\n", client->id); |
| 50 | + char buff[100]; |
| 51 | + snprintf(buff, 100, "WServer: Client with id:%u left the room, %u members on-line", client->id, ws.activeClientsCount()); |
| 52 | + ws.textAll(client->id, buff); |
| 53 | + break; |
| 54 | + } |
| 55 | + |
| 56 | + // new messages from clients |
| 57 | + case WSocketClient::event_t::msgRecv : |
| 58 | + // any incoming messages we must deQ and discard, |
| 59 | + // there is no need to resend it back to, it's handled on the server side. |
| 60 | + // If not discaded messages will overflow incoming Q |
| 61 | + client->dequeueMessage(); |
| 62 | + break; |
| 63 | + |
| 64 | + default:; |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | + |
| 69 | +void setup() { |
| 70 | + Serial.begin(115200); |
| 71 | + |
| 72 | + WiFi.mode(WIFI_STA); |
| 73 | + WiFi.begin(WIFI_SSID, WIFI_PASSWD); |
| 74 | + |
| 75 | + // Wait for connection |
| 76 | + while (WiFi.status() != WL_CONNECTED) { |
| 77 | + delay(250); |
| 78 | + Serial.print("."); |
| 79 | + } |
| 80 | + Serial.println(); |
| 81 | + Serial.println("Connected to WIFI_SSID"); |
| 82 | + Serial.print("IP address: "); |
| 83 | + Serial.println(WiFi.localIP()); |
| 84 | + Serial.println(); |
| 85 | + Serial.printf("to access WebChat pls open http://%s/\n", WiFi.localIP().toString().c_str()); |
| 86 | + |
| 87 | + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { |
| 88 | + // need to cast to uint8_t* |
| 89 | + // if you do not, the const char* will be copied in a temporary String buffer |
| 90 | + request->send(200, "text/html", (uint8_t *)htmlChatPage, strlen(htmlChatPage)); |
| 91 | + }); |
| 92 | + |
| 93 | + // keep TCP/WS connection open |
| 94 | + ws.setKeepAlive(20); |
| 95 | + |
| 96 | + /* |
| 97 | + Enable server echo to reflect incoming messages to all participans of the current chat room |
| 98 | + */ |
| 99 | + ws.setServerEcho(true, true); // 2nd 'true' here is 'SplitHorizon' - server will reflect all message to every peer except the one where it came from |
| 100 | + |
| 101 | + server.addHandler(&ws); |
| 102 | + |
| 103 | + server.begin(); |
| 104 | +} |
| 105 | + |
| 106 | + |
| 107 | +void loop() { |
| 108 | + // nothing to do here |
| 109 | + delay(100); |
| 110 | +} |
0 commit comments