// пример работы через Websocket + HTTP вручную с WiFiServer #include #define AP_SSID "Alex" #define AP_PASS "alexpass" // отключаем встроенную реализацию HTTP+WS // #define GH_NO_STREAM #define GH_NO_HTTP #define GH_NO_WS // #define GH_NO_MQTT // указываем что трансфер файлов будет по вебсокет, // потому что работу с файлами силами сервера мы не написали #define GH_NO_HTTP_TRANSFER #include GyverHub hub; // ======================= WS ======================= #include class HubWS : public gh::Bridge { public: HubWS(void* hub) : gh::Bridge(hub, gh::Connection::WS, GyverHub::parseHook), ws(GH_WS_PORT, "", "hub") {} void begin() { ws.onEvent([this](uint8_t num, WStype_t type, uint8_t* data, size_t len) { switch (type) { case WStype_CONNECTED: setFocus(); break; case WStype_DISCONNECTED: clearFocus(); break; case WStype_TEXT: clientID = num; parse(sutil::AnyText((char*)data, len)); break; default: break; } }); ws.begin(); } void end() { ws.close(); } void tick() { ws.loop(); } void send(gh::BridgeData& data) { if (data.text.pgm()) { char buf[data.text.length()]; data.text.toStr(buf); if (data.broadcast) { ws.broadcastTXT((uint8_t*)buf, data.text.length()); } else { ws.sendTXT(clientID, (uint8_t*)buf, data.text.length()); } } else { if (data.broadcast) { ws.broadcastTXT(data.text.str(), data.text.length()); } else { ws.sendTXT(clientID, data.text.str(), data.text.length()); } } } private: WebSocketsServer ws; uint8_t clientID = 0; }; HubWS ws(&hub); // ======================= HTTP ======================= #include // делаем класс на основе Bridge class HubHTTP : public gh::Bridge { public: HubHTTP(void* hub) : gh::Bridge(hub, gh::Connection::HTTP, GyverHub::parseHook), server(GH_HTTP_PORT) {} void begin() { server.begin(); } void end() { server.stop(); } void tick() { WiFiClient client = server.accept(); if (client) { String req = client.readStringUntil('/'); // "GET /" req = client.readStringUntil('\r'); // первая строка до конца while (client.available()) client.read(); // пропускаем остальное // нас интересует url /hub/... HTTP/, берём нужный сегмент int start = req.indexOf(F("hub/")); int end = req.indexOf(F(" HTTP/")); if (start < 0 || end < 0) return; req = req.substring(start + 4, end); // отвечаем клиенту с no-cors хэдером (для работы с внешним сайтом или приложением) client.print(F( "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" "Access-Control-Allow-Origin:*\r\n" "Access-Control-Allow-Private-Network: true\r\n" "Access-Control-Allow-Methods:*\r\n\r\n")); // запоминаем клиента, тк ответ ему будет внутри send client_p = &client; parse(req); client_p = nullptr; } } void send(gh::BridgeData& data) { if (client_p) client_p->print(data.text); } WiFiServer server; private: // будем хранить указатель на клиента для ответов WiFiClient* client_p = nullptr; }; HubHTTP http(&hub); // ======================= BUILD ======================= // билдер void build(gh::Builder& b) { static int val; b.Title(F("Hello!")); b.Slider(&val); } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(AP_SSID, AP_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.println(WiFi.localIP()); hub.config(F("MyDevices"), F("ESP"), F("")); hub.onBuild(build); hub.addBridge(&http); hub.addBridge(&ws); hub.begin(); } void loop() { hub.tick(); }