khoih-prog / WebSockets2_Generic

A WebSocket Server and Client library for Arduino, based on RFC6455, for writing modern Websockets applications. Now support ESP8266, ESP32 (including ESP32-S2 Saola, AI-Thinker ESP-12K, WT32_ETH01, etc.), nRF52, SAMD21, SAMD51, SAM DUE, STM32F/L/H/G/WB/MP1, Teensy, RP2040-based, etc. boards, with WiFiNINA, Teensy 4.1 NativeEthernet/QNEthernet, Ethernet W5x00 / ENC28J60 / LAN8742A / LAN8720, ESP8266 / ESP32-AT modules/shields, as well as SINRIC / Alexa / Google Home
GNU General Public License v3.0
82 stars 30 forks source link

Enhancement: #2

Closed jakespeed1311 closed 3 years ago

jakespeed1311 commented 4 years ago

Hello,

Unfortunately I can contribute less code than I would like to, but thanks again for the great work.

The new unblocking function was successfully tested, thanks! But unfortunately it reads the websocket connection immediately after sending the echo. This is unfortunately exactly the problem. Actually, it's just the server that outputs the data until the web socket is closed by the client.

What would I like to achieve.

  1. the client connects to the webserver and presses a html butt, we say "Enable Logging".
  2. a new page is called and from the webserver and in it is a javascript that opens the websocket to the server.
  3. the browser now sends its request to the server via the websocket... which in turn replies with a string example current time (actually I want to display the debug output of a traffic " DCC ". )
  4. from now on the browser (javascript) waits for data from the server to output it as http.
  5. the server outputs the current time/DCC data via the socket
  6. enough of the output is after 5 min or on e.g. an "exit" butten the Websock bzzw the logging is terminated.

As I understood it should work like this, but step 3 closes the websock at the end of the logging process. For it to work the Javascript would have to rebuild the websock again and again. That would be the same with Ajax and because Ajax asks for time you want a websocket that can send / receive data bidirectional and reduce the html overhead.

Is it possible to implement this? I try to give you the full understand what I need, if not please ask. Or is that possible and I have overlooked how !

greeting Jake

khoih-prog commented 4 years ago

It's totally difficult to guess what you're doing and the problem you're experiencing.

Please post the code and how to duplicate the issue, then I can have further look. Just remember we could have saved a lot of time if you could specify and identify the exact issue and enhancement.

jakespeed1311 commented 4 years ago

Hello, I'm sorry I didn't make myself clear. I'm trying to make it better now. Please forgive me. It's certainly not my intention to waste your time. I have now changed the example to provide the browser with the appropriate web page with javascript. I did not open another browser window to not inflate it unnecessarily.

After the html code is loadedin Chrome it opens an websock to the Arduino by sending an string on init. The arduino then is sending an answer with an number. If the client was not deleted normlay the loop will send the string till the int var is overflowing. But it stops after sending one Answer and cloase the Websocket.

greedings Jake

/****************************************************************************************************************************
  SAMDUE-Ethernet_AdvancedWebServer.ino  
  For SAM DUE with Ethernet module/shield.

  Based on and modified from Gil Maimon's ArduinoWebsockets library https://github.com/gilmaimon/ArduinoWebsockets
  to support STM32F/L/H/G/WB/MP1, nRF52 and SAMD21/SAMD51 boards besides ESP8266 and ESP32

  The library provides simple and easy interface for websockets (Client and Server).

  Example first created on: 10.05.2018
  Original Author: Markus Sattler

  Built by Khoi Hoang https://github.com/khoih-prog/Websockets2_Generic
  Licensed under MIT license
  Version: 1.0.6

  Version Modified By   Date      Comments
  ------- -----------  ---------- -----------
  1.0.0   K Hoang      14/07/2020 Initial coding/porting to support nRF52 and SAMD21/SAMD51 boards. Add SINRIC/Alexa support
  1.0.1   K Hoang      16/07/2020 Add support to Ethernet W5x00 to nRF52, SAMD21/SAMD51 and SAM DUE boards
  1.0.2   K Hoang      18/07/2020 Add support to Ethernet ENC28J60 to nRF52, SAMD21/SAMD51 and SAM DUE boards
  1.0.3   K Hoang      18/07/2020 Add support to STM32F boards using Ethernet W5x00, ENC28J60 and LAN8742A
  1.0.4   K Hoang      27/07/2020 Add support to STM32F/L/H/G/WB/MP1 and Seeeduino SAMD21/SAMD51 using
                                  Ethernet W5x00, ENC28J60, LAN8742A and WiFiNINA. Add examples and Packages' Patches.
  1.0.5   K Hoang      29/07/2020 Sync with ArduinoWebsockets v0.4.18 to fix ESP8266 SSL bug.
  1.0.6   K Hoang      06/08/2020 Add non-blocking WebSocketsServer feature and non-blocking examples.  
 *****************************************************************************************************************************/

#include "defines.h"

#include <WebSockets2_Generic.h>

#include <EthernetWebServer.h>

using namespace websockets2_generic;

WebsocketsServer SocketsServer;

#define WEBSOCKETS_PORT     8080

EthernetWebServer server(80);

int reqCount = 0;                // number of requests received
uint32_t wscounter =0;
void handleRoot()
{
#define BUFFER_SIZE    2200

  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,
  /*
           "<html>\
<head>\
<meta http-equiv='refresh' content='1'/>\
<title>AdvancedWebServer %s</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h2>WebSockets&WebServer!</h2>\
<h3>both on %s</h3>\
<p>Uptime: %d d %02d:%02d:%02d</p>\
<img src=\"/test.svg\" />\
</body>\
</html>", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60);

//<-- <meta http-equiv='refresh' content='1'/>\ -->
*/
"<html>\
<head>\
<title>AdvancedWebServer %s</title>\
<style>\
<meta http-equiv='refresh' content='10'/>\ 
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
   <script language = \"javascript\" type = \"text/javascript\">\
      var wsUri = \"ws://192.168.2.93:8080\";\
      var output;\
      function init() {\
         output = document.getElementById(\"output\");\
         testWebSocket();    } \n\
      function testWebSocket() {\
         websocket = new WebSocket(wsUri);\
         websocket.onopen = function(evt) {\
            onOpen(evt) };\n\
        websocket.onclose = function(evt) {\
            onClose(evt) };\n\  
         websocket.onmessage = function(evt) {\
            onMessage(evt)   };\n\
         websocket.onerror = function(evt) {\
            onError(evt) };   }\
      function onOpen(evt) {\
         writeToScreen(\"CONNECTED\");\
         doSend(\"OpenLoggingData\");  }\n\
      function onClose(evt) {\
         writeToScreen(\"Closed\");}\n\
       function onMessage(evt) {\
         writeToScreen('<span style = \"color: blue;\">RESPONSE: ' +\
            evt.data+'</span>'); websocket.close(); }\n\
      function onError(evt) {\
         writeToScreen('<span style=\"color: red;\">ERROR:</span> ' + evt.data);  }\n\
      function doSend(message) {\
         writeToScreen(\"SENT: \" + message); websocket.send(message);   }\n\
      function writeToScreen(message) {\
       var pre = document.createElement(\"p\"); \ 
       pre.style.wordWrap = \"break-word\"; \
       pre.innerHTML = message; output.appendChild(pre); }\
       window.addEventListener(\"load\", init, false);\n\
   </script>\
</head>\
<body>\
<h2>WebSockets&WebServer!</h2>\
<h3>both on %s</h3>\
<p>Uptime: %d d %02d:%02d:%02d</p>\
<img src=\"/test.svg\" />\
<div id = \"output\"></div> \
</body>\
</html>", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60);

  server.send(200, "text/html", temp);

}

void handleNotFound()
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for (uint8_t i = 0; i < server.args(); i++)
  {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }

  server.send(404, "text/plain", message);
}

void drawGraph()
{
  String out;
  out.reserve(3000);
  char temp[70];
  out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"310\" height=\"150\">\n";
  out += "<rect width=\"310\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"5\" stroke=\"rgb(0, 0, 0)\" />\n";
  out += "<g stroke=\"blue\">\n";

  int y = rand() % 130;

  for (int x = 15; x < 300; x += 15)
  {
    int y2 = rand() % 130;
    sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 15, 140 - y2);
    out += temp;
    y = y2;
  }

  out += "</g>\n</svg>\n";

  server.send(200, "image/svg+xml", out);
}

void setup()
{
#if (USE_ETHERNET_LIB || USE_ETHERNET2_LIB || USE_ETHERNET_LARGE_LIB)
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
#endif

  Serial.begin(115200);
  while (!Serial);

  Serial.println("\nStarting WebSockets2_Generic SAMDUE-Ethernet_AdvancedWebServer on " + String(BOARD_NAME));
  Serial.println("Ethernet using " + String(ETHERNET_TYPE));

  for (uint8_t t = 4; t > 0; t--)
  {
    Serial.println("[SETUP] BOOT WAIT " + String(t));
    Serial.flush();
    delay(1000);
  }

  // start the ethernet connection and the server:
  // Use Static IP
  Ethernet.begin(mac, serverIP);
  //Configure IP address via DHCP
  //Ethernet.begin(mac);

  // server address, port and URL
  Serial.print("WebSockets Server IP address: ");
  Serial.println(Ethernet.localIP());

  SocketsServer.listen(WEBSOCKETS_PORT);

  Serial.print(SocketsServer.available() ? "WebSockets Server Running and Ready on " : "Server Not Running on ");
  Serial.println(BOARD_NAME);
  Serial.print("IP address: ");
  Serial.print(Ethernet.localIP());
  Serial.print(", Port: ");
  Serial.println(WEBSOCKETS_PORT);    // Websockets Server Port

  server.on("/", handleRoot);
  server.on("/test.svg", drawGraph);
  server.on("/inline", []()
  {
    server.send(200, "text/plain", "This works as well");
  });

  server.onNotFound(handleNotFound);
  server.begin();
}

void loop()
{
  server.handleClient();  //Ethernet

  WebsocketsClient client = SocketsServer.accept();

  if (client.available())
  {
    WebsocketsMessage msg = client.readNonBlocking();

    // log
    Serial.print("Got Message: ");
    Serial.println(msg.data());

    // return echo  but wenn aktive after the send the websock was closed.
   // client.send("Echo: " + msg.data());

   ++wscounter;
   Serial.println(wscounter);
   String output =" Logging data_" + String(wscounter);
   Serial.println(output);

   client.send(output);
   client.send( String(wscounter));

    // close the connection
   // client.close();
  }
}
khoih-prog commented 4 years ago

But it stops after sending one Answer and cloase the Websocket.

It's been continuing running almost 4 hrs without any problem.

Selection_492

The library and the example are just examples, and they just provide certain features. They can be used without any problem in all use cases. You have to understand all their features, then write the correct and working codes to use them.

I think you have to check your HTML code. and modify it to fix your purpose.

jakespeed1311 commented 4 years ago

Hello, i have only the website, there is no other client that is opening an connection to the websock!
And my html code is an examble and i beleve it's not closing the connection. And polling for websock data is not the clue, thast is against the websock definiton.

My "knowledge" is from here. https://www.tutorialspoint.com/websockets/websockets_quick_guide.htm

But ok if this is my error, i have to find out the html problem. Tanks Jake

jakespeed1311 commented 4 years ago

Hello,

i found this site. https://libwebsockets.org/testserver/  

 

I have to analyze what they do, but this is nearly what i need.

 

Tanks,

Jake

   

Gesendet: Freitag, 07. August 2020 um 20:14 Uhr Von: "Khoi Hoang" notifications@github.com An: "khoih-prog/WebSockets2_Generic" WebSockets2_Generic@noreply.github.com Cc: "Jake" jakespeed@web.de, "Author" author@noreply.github.com Betreff: Re: [khoih-prog/WebSockets2_Generic] Enhancement: (#2)

 

But it stops after sending one Answer and cloase the Websocket.

It's been continuing running almost 4 hrs without any problem.

The library and the example are just examples, and they just provide certain features. They can be used without any problem in all use cases. You have to understand all their features, then write the correct and working codes to use them.

I think you have to check your HTML code. and modify it to fix your purpose.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.