Git Product home page Git Product logo

Comments (13)

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024 1

Yes... according to RFC, you seem to be right. However, the only header I receive are those null-bytes from time to time... the implementation I have (which is a forked one) might be wrong at some point.
I'll investigate further.

Once again, big big big thanks for your support and your time... really important for me and my project.
Wish you all the best Gil,
Many many thanks,
A.

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

Hi,

I am currently answering from mobile, and I will only be able to fully address your issues this weekend.

However, regarding masking. There is a little trick I use which is to mask the messages with the key "/x00/x00/x00/x00" so message are indeed masked (the mask flag is on) but the masking process is a no-op (so I'm saving space and time, which I felt are especially relevant for embedded). Masking should not fail on your end, does your code handles null masks well?

If I am missing a point I'm sorry, as I've said I will have time to read and answer more thoroughly this weekend.

Best regards,
Gil.

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

I'm not sure I got what you said... adding "/x00/x00/x00/x00" in front of the string turns on the mask flag?
...
Later edit: Tested, doesn't work.

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

No, that's not what I meant.
All upstream messages are masked, but they are masked using a null key so the masked result is exactly the same as the unmasked, but it is still considered masked.

Try using Wireshark, you will see the messages are masked (should be).

Best regards,
Gil.

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

I see now what you're saying... basically it flags it as masked but is not really masked.
My code does handle this situation, however the behavior is weird (see image):

In the same loop (and almost same text), 90% of the time the messages are sent incorrectly:
For a single send() call, the library sends firstly a request with the null bytes (without the text), and afterwards sends the text in a second call (marked as red in the screenshot).

In 10% of the times, it sends it correctly, null bytes + text in a single call (marked as green in the screenshot).

I don't really understand why... I'll try to investigate further, though my test loop is so simple:

void loop() {
  if (client.available()) {
    client.poll();
    if(i++ % 10000 == 0) {
      Serial.println("Client still connected.");
      String  str_i  = String(i, DEC);
      String  text = "{\"type\":\"user-msg\",\"name\":\"Jess D_Arduino\",\"message\":\"Here we are again, sequence [";
              text = text + str_i;
              text = text + "]...\"}";
      client.send(text);
    }
  } else {
    Serial.println("Client Disconnected!");
    delay(5000);
  }
}

Hit me if you have any ideas... (and once again, I appreciate your time) !

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

Tried with a simple plain text in the loop... client.send("This is a nice text.");, same result: only one correct sent from many (see image).

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

Oh, well the library always sends 2 packets: one for the header and one for the content. The ESP sometimes choose to optimize and send those together, but it is not guaranteed neither is it necessary.

Servers should always first read the header, see how much content there is (according to the header) and only then read that many bytes from the socket.

I haven't looked, but it is possible that your code tries to read everything at once?

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

Well, somehow - yes - on the server-side, I am reading a single message in a single iteration of the loop (and to be truly honest, I find it normal to be this way).

Is kind'a surprising to hear that mostly it sends two separate packets and sometimes "for optimization purposes" sends it all at once....

Is there any way to set the ESP/Libraries to send the package/message "all-at-once" ? I mean, would be great to have some consistency in the workflow of the code... not alternating all the time from a method to another.

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

Even the browsers implementation send it in a single package, so the RFC must state a single package design (header + body) on the same 'shot', so there should't be any reason to have two or more...

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

It shouldn't matter to you. As a socket user you should call read with the required length and the code will block until you get that many bytes. Internally the TCP stream can be fragmented to any numbers of frames but you should know how many bytes you expect to read, and only continue execution when you have read that many bytes.

Can you share the code that reads from a socket in your implementation? I think it might be easier to explain with it.

from arduinowebsockets.

adelin-mcbsoft avatar adelin-mcbsoft commented on May 23, 2024

I have the feeling that we might be missing the point around...
TCP fragmentation & co. is part of another layer, way before we come to the socket implementation, isn't it? That is handled & solved by the network interface.

In my implementation, i use the socket_recv function in PHP (exaclty while(socket_recv($changed_socket, $socket_data, 1024, 0) >= 1) { ) which is being triggered at every newly received data in the socket (I'm reading a maximum of 1024 bytes in length, because usually I don't need longer lines -- and usually, I expect text only).

Given the current situation, to get both the header mask & the body, the loop must go through 2 iteratons most of the time and compute them afterwards, compared with the case where it is sent in a single line. And here's where all this issue's coming from...

So it all resumes to a single-question: is it a way to force ESP to send it in a single-line, like all the browsers do? Would solve the entire problem and wouldn't require additional workarounds.

(I mean, browsers mask the message differently - like in the real way... so there isn't any header required - therefore, is a single line with the body).

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

Your issue is the receiving code, you should not read an arbitrary number of 1024 bytes. You should read 2 bytes which are the first and common part of the header, then read extra bytes if necessary (for long messages). At this point you should know the body length using all the header data you received, then read that many bytes from the socket. All of your calls should be using the MSG_WAITALL flag. For example, your code will fail to read a whole message in case it's longer than 1024. Websockets is very well defined, you should follow the RFC and receive from a socket accordingly (the header is there for a reason).

from arduinowebsockets.

gilmaimon avatar gilmaimon commented on May 23, 2024

Thank you, your contribution to this project is really big for me and I appreciate and enjoy your issues.

Let me know if you need any help with the php implementation, I know some basic PHP and the syntax is C-like enough for me. If you have any questions on implementing WS, I would love to help.

My email is [email protected].

Again thank you.

Best wishes,
Gil.

from arduinowebsockets.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.