ssilverman / QNEthernet

An lwIP-based Ethernet library for Teensy 4.1 and possibly some other platforms
GNU Affero General Public License v3.0
81 stars 24 forks source link

Websocket with khoih-prog´s AsyncWebServer_Teensy41 #25

Closed Mike0675 closed 1 year ago

Mike0675 commented 1 year ago

Hi, I try to use Websockets with AsyncWebServer_Teensy41. I don´t know the Problem is in QNEthernet. Looking on the incoming Data with Wireshark i´ve see the OPCODE is not transfered how it should. It should be 10000001 but is wrong. The send Welcome-Message is there.

The OPCODE is build in webSocketSendFrame() going to AsyncClient::add() where ist is DEC129 and then going to tcp_write(). There I lose Track couse of my limited knowledge (Im hobbyist).

ArduinoIDE is 1.8.19 QNEthernet is 0.17.0 Teensy41_AsyncTCP is 1.1.0 AsyncWebServer_Teensy41 is 1.1.2-1

`/**** Async_AdvancedWebServer.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet

For Teensy41 with QNEthernet

AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet

Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 Licensed under GPLv3 license

Copyright (c) 2015, Majenko Technologies All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of Majenko Technologies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****/

if !( defined(CORE_TEENSY) && defined(IMXRT1062) && defined(ARDUINO_TEENSY41) )

error Only Teensy 4.1 supported

endif

// Debug Level from 0 to 4

define _TEENSY41_ASYNC_TCPLOGLEVEL 1

define _AWS_TEENSY41LOGLEVEL 1

define SHIELD_TYPE "Teensy4.1 QNEthernet"

if (_AWS_TEENSY41LOGLEVEL > 3)

warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error

endif

define USING_DHCP true

//#define USING_DHCP false

if !USING_DHCP

// Set the static IP address to use if the DHCP fails to assign IPAddress myIP(192, 168, 179, 8); IPAddress myNetmask(255, 255, 255, 0); IPAddress myGW(192, 168, 179, 1); //IPAddress mydnsServer(192, 168, 2, 1); IPAddress mydnsServer(8, 8, 8, 8);

endif

include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet

using namespace qindesign::network;

include

AsyncWebServer server(80); AsyncWebSocket ws("/ws");

int reqCount = 0; // number of requests received

const int led = 13;

void handleRoot(AsyncWebServerRequest *request) { digitalWrite(led, 1);

define BUFFER_SIZE 400

char temp[BUFFER_SIZE]; int sec = millis() / 1000; int min = sec / 60; int hr = min / 60; int day = hr / 24;

snprintf(temp, BUFFER_SIZE - 1, "\

\ \ AsyncWebServer-%s\ \ \ \

AsyncWebServer_Teensy41!

\

running on %s

\

Uptime: %d d %02d:%02d:%02d

\ \ \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); request->send(200, "text/html", temp); digitalWrite(led, 0); } void handleNotFound(AsyncWebServerRequest *request) { digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += request->url(); message += "\nMethod: "; message += (request->method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += request->args(); message += "\n"; for (uint8_t i = 0; i < request->args(); i++) { message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; } request->send(404, "text/plain", message); digitalWrite(led, 0); } void drawGraph(AsyncWebServerRequest *request) { String out; out.reserve(4000); char temp[70]; out += "\n"; out += "\n"; out += "\n"; int y = rand() % 130; for (int x = 10; x < 300; x += 10) { int y2 = rand() % 130; sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); out += temp; y = y2; } out += "\n\n"; request->send(200, "image/svg+xml", out); } void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) { if (type == WS_EVT_CONNECT) { Serial6.println("Websocket client connection received"); client->text("Hello from Teensy41 Server"); } else if (type == WS_EVT_DISCONNECT) { Serial6.println("Client disconnected"); } } void setup() { pinMode(led, OUTPUT); digitalWrite(led, 0); Serial6.begin(115200); while (!Serial6 && millis() < 5000); delay(200); Serial6.print("\nStart Async_AdvancedWebServer on "); Serial6.print(BOARD_NAME); Serial6.print(" with "); Serial6.println(SHIELD_TYPE); Serial6.println(ASYNC_WEBSERVER_TEENSY41_VERSION); delay(500); #if USING_DHCP // Start the Ethernet connection, using DHCP Serial6.print("Initialize Ethernet using DHCP => "); Ethernet.begin(); #else // Start the Ethernet connection, using static IP Serial6.print("Initialize Ethernet using static IP => "); Ethernet.begin(myIP, myNetmask, myGW); Ethernet.setDNSServerIP(mydnsServer); #endif if (!Ethernet.waitForLocalIP(5000)) { Serial6.println(F("Failed to configure Ethernet")); if (!Ethernet.linkStatus()) { Serial6.println(F("Ethernet cable is not connected.")); } // Stay here forever while (true) { delay(1); } } else { Serial6.print(F("Connected! IP address:")); Serial6.println(Ethernet.localIP()); } #if USING_DHCP delay(1000); #else delay(2000); #endif ws.onEvent(onWsEvent); server.addHandler(&ws); server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) { handleRoot(request); }); server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) { drawGraph(request); }); server.on("/inline", [](AsyncWebServerRequest * request) { request->send(200, "text/plain", "This works as well"); }); server.onNotFound(handleNotFound); server.begin(); Serial6.print(F("HTTP EthernetWebServer is @ IP : ")); Serial6.println(Ethernet.localIP()); } void loop() { }`
ssilverman commented 1 year ago

I haven’t spent time with that library, so can’t guarantee it uses QNEthernet properly. In addition, QNEthernet isn’t designed to be used asynchronously unless used in a very specific way.

I also don’t have much experience with WebSockets nor the time to learn it and verify that library. I’m pretty sure that library requires rework. I’m afraid I can’t be much help here without spending probably a week or three diving in.

ssilverman commented 1 year ago

See this recent thread, it might be useful to you: https://forum.pjrc.com/threads/71862-Teensy-4-1-ethernet-with-mongoose-network-library

ssilverman commented 1 year ago

Update for future readers: the user khoih-prog has published a number of asynchronous libraries that claim to use QNEthernet, but don’t actually use it. This is misleading. I don’t recommend using them.

ClosetGeek-Git commented 12 months ago

I'm in the middle of prototyping a Teensy 4.1 using khoih-prog's WebSockets2_Generic library. I'm curious what you would suggest if not a khoih-prog lib?

ssilverman commented 12 months ago

Thank you for the question. Those asynchronous libraries just use some Ethernet initialization code from QNEthernet plus the lwIP code I’ve included. It’s misleading to say that they use QNEthernet at all because my library is designed specifically for non-concurrent use and to have an Arduino-style API.

Note that I don’t think Websockets2_Generic uses the “asynchronous” stuff.

The author clearly has done a bunch of work to adapt other libraries for use on the Teensy, which is nice. I mean, go ahead and use them if they work for you. I can chat more about specifics privately if you like.

ssilverman commented 12 months ago

Note that I don’t think Websockets2_Generic uses the “asynchronous” stuff.