Comments (13)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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)
- ESP32-Server Not Working Properly receives one msg and gets disconnected HOT 3
- How to know hostname and IP from client? HOT 1
- esp32 to wss python server
- ESP32 Websocket Client doesn't connect to Node.js Websocket server HOT 3
- poll() disconnects client HOT 7
- How to get a reference of the web socket client that dispatched the msg callback
- Hieromon/AutoConnect & WebSockets Client on ESP8266 - Can't Establish wss
- Secured-ESP8266-Client can't seem to receive any messages while connection is open HOT 1
- Compilation error: 'WebsocketsClient' does not name a type ?? HOT 3
- Getting a error from the TCPServer using the Arduino GIGA R1 WIFI on the ESP-32Client code. HOT 3
- ESP32-CAM WebSocket Server: Failure to Stream Camera Feed after Page Refresh or Multiple Connections
- WSS Connection error
- [ 5236][E][WiFiClient.cpp:313] setSocketOption(): fail on -1, errno: 9, "Bad file number" HOT 2
- Reconnecting after lost connection HOT 2
- Disconnecting almost inmediately
- Random disconnects, fails on binary ping including 0x00 HOT 1
- Issue with WSS and ESP 32 HOT 4
- Esp32 WebSocket Client won't work with WebSocket Node.js server. HOT 3
- Client-Message-Buffer
- ESP32 Server disconnected when receiving messages
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arduinowebsockets.