-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ESP32: Websocket client ESP32 library in pure Lua #2694
Conversation
This is a library for a websocket client for ESP32 written in pure Lua. This is a completely license-free library I wrote on my own as my contribution back to the nodemcu community.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great contribution. So now there will be websocket for esp32 also
lua_examples/websocket.lua
Outdated
@@ -0,0 +1,49 @@ | |||
-- ChiliPeppr Websocket client library for Lua ESP32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually lua_module examples are right besides the module in the same folder.
See http module for example,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I did it like the email module which had a folder in examples and a folder in lua_modules. I can do it like http though if that's the more preferred format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok checked some others and both ways seem to be common.
So a task to decide for Collaborator (or not to decide)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved them to the same directory. I think it's fine that way.
lua_examples/websocket.lua
Outdated
end) | ||
|
||
-- Use ChiliPeppr wifi library to auto-connect to wifi | ||
wf = require("esp32_wifi") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the example maybe should not require external modules. Does it also work with the standard wifi module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it just needs normal connectivity. I should remove that.
-- print("Got receive: " .. c) | ||
|
||
-- see if we are good to go here | ||
if isHdrRecvd == false then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the header is not sent in a single packet?
What if data is sent in the same packet as the header?
What if no 101 status is sent?
It obviously works against the server you use, but might not work against other ws servers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I suppose that scenario could happen. I wouldn't have the time to go test that though. It still may be worth ignoring that potential scenario to get this websocket.lua into this repo and then allow others to tweak from there if they see that as an issue as a bug later on. The notion is that the header comes in first, so I think probability is high that the first TCP packet is going to have more than those needed 20 chars or so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably valid for that case. But what about the other ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From reading the standard docs again, your other scenarios would mean the server is not following the websocket standard. I think we're good here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I read it the websocket standard just defines logical websocket packets.
The underlying tcp packet size and fragmentation may be different.
The relevant part in the RFC seems to be
After a successful handshake, clients and servers transfer data back
and forth in conceptual units referred to in this specification as
"messages". On the wire, a message is composed of one or more
frames. The WebSocket message does not necessarily correspond to a
particular network layer framing, as a fragmented message may be
coalesced or split by an intermediary.
so two fragments might also be coalesced to one frame.
-- print("Our own count of len:", string.len(data)) | ||
|
||
-- calc m.lenExpected for next time back into this method | ||
m.lenExpected = m.lenExpected - string.len(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if data also contains (the start of) the next message?
Then string.len(data) would be greater than lenExpected and only the lenExpected first bytes would have to be handled here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I feel like that's against the websocket standard, but I'm not totally sure. In my testing that never occurred and I use it so much in the real world I've never run into that bug. I don't think I'd have time to test that further. I still think it may be worth ignoring this item, but up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know if this happens. Just saw that for MQTT it was needed to cover also this case.
See #2571
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My other note would also apply here of corse.
Sorry for being so insistent about this. Just bad if things work sometimes and sometimes not.
But maybe a message would be enough as a first step.
Its not up to me to decide after all.
print("Websocket expecting " .. m.lenExpected .. " more chars of data") | ||
else | ||
-- done with data. do callback | ||
m.lenExpected = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be necessary in the case mentioned above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice, what I've seen is you get lots of "receive" events from the TCP connection on the incoming data and you don't get all the data, however, you know how much you're going to get due to the frame header. So I'm only trying to solve for the multiple function calls that occur until you get the whole amount of data. Then I give you the callback. I don't think the scenario of getting more data for the next frame is part of the standard. So I'm pretty sure I'm safe here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this has nothing to do with the standard. Its only about packaging the information in one or more packages.
Still might be safe in most cases. Maybe a warning would be nice at first, so in case it happens the user can spot it esily.
But I am not the one to decide what goes in anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're thinking of m.lenExpected in a different way than how it's being used. But, it's my fault for printing this message out. I just commented out that line since it really was just a debug line during development so I could follow what was happening. Check out the new commit. I think this cleans this part up.
Added error statements. Moved websocket_test.lua to same directory. Removed test code that relied on 3rd party libraries.
Ok, made the changes based on your feedback. I think this is good to go. For what it's worth, if you check out this Youtube video of the websocket client in action: I'm sending tons of data back and forth over this websocket to jog my CNC machine around, so it pushes that websocket code to the limit and it works perfectly. |
Do you think there is a good way to add to the https://nodemcu.readthedocs.io/en/dev-esp32/ for a Lua module? I've never seen anybody do that yet, so it gets lost to folks that these pure Lua modules even exist, yet they're super valuable to the community. |
Great, yes we need this. @galjonsfigur did a great job reorganizing this for the Can you help us get there for the ESP32 branch? |
My only concern here is that of consistency and re-use between ESP8266 and ESP32. For the older chip we have had a C module for websockets for over two years. Can or is this Lua module generic enough to be usable on both? If so, should we retire the C module? |
This is generic enough, but I would say it does not support long packet
length and I think the C version does.
…On Fri, Mar 15, 2019 at 2:36 PM Marcel Stör ***@***.***> wrote:
My only concern here is that of consistency and re-use between ESP8266 and
ESP32. For the older chip we have had a C module for websockets
<https://nodemcu.readthedocs.io/en/dev/modules/websocket/> for over two
years.
Can or is this Lua module generic enough to be usable on both? If so,
should we retire the C module?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#2694 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AHidbaZ4AQ0isD7dQxT73Tvi4EUr0FOkks5vXBJVgaJpZM4b1Om_>
.
|
Oh PLEASE, do not retire the C module. |
@jmd13391 Say why? |
At a quick glance the c implementation does handle fragmentation and coalescation in a robust way. |
Hmm. It might be worth just cancelling this pull request then. I've struggled with not having a websocket client on ESP32, but it's probably nicer to port the C library. That's beyond what I would have time to do though, so maybe we just punt on this becoming part of the dev-esp32 repo. |
Maybe it still could serve as an interim solution until the C module gets available. |
this would fix #2186 |
hi, Just curious when this will get merged into the dev-esp32 branch. |
It might be better for this to just be put in the Lua modules directory at https://github.com/nodemcu/nodemcu-firmware/wiki/Lua-modules-directory |
@chilipeppr I wouldn't mind hosting modules provided (and maintained) but committers in the repo 😉 I think we all lost track of whether reviewer @HHHartmann was happy to approve this or not. |
As stated above:
So it might be that this Implementation will not work with all server/network combinations because the messages might not be aligned with the packets being sent, So my conclusion was
|
Maybe this could also be the first entry in https://github.com/nodemcu/nodemcu-firmware/wiki/Lua-modules-directory |
I think this is the solution. We should close this PR and move all Lua modules to this wiki. I'm advocating the same also for C modules. There are lots of PRs here, including my own, asking the maintainers to merge drivers for their hardware. For C modules I am advocating for this: #3100, then we can host a registry of modules, similar to npm as a next step, liberating the main repo of the burden of hosting everything, while allowing permissionless creation of new modules. |
See #3034. The intention is to host "endorsed" Lua modules here and use the wiki as a registry for others. What endorsed means has yet to be defined, though. We were discussing to require at least unit tests. |
I wouldn't make a distinction between endorsed and not endorsed. If useful, the community will endorse them via repository stars, contributions, etc. I would move all existing lua modules out and actually use that move to kickstart the wiki with some quality content that encourage people to add their stuff there as well. If you guys give me some org access, I can do this work: for existing modules, I would create a repo for each, move the code there along with its git history and link those in the wiki. That way, each module can have its own space for PRs and contributions. For new modules, people can just go create their own repo and link it in the wiki themselves. |
For the C modules, I am against moving them out. The reason is that the modules in the nodemcu-firmware repo are supposed to work, we keep them running as the underlying lua vm moves forward. The difficulty is the level of review of changes to these external modules. They won't get the attention from the core maintainers, and when they stop working, it is likely that the users will complain to nodemcu-firmware rather than this other repo..... |
For the existing C modules, I am proposing they move to a separate repository but within the nodemcu GitHub org, with this criteria: Modules that expose internal ESP hardware or are core software libraries anyone uses, such as http, json, mqtt, etc. These can be tested by anyone with a dev board: STAY as is. Other modules already there that do not meet the above criteria: move to a new repo within the nodemcu org. Example: dht, bme280... New modules from now on that drive external hardware: Owner's repo as proposed in #3100
As exposed above, these moved modules would stay within the org and we can automate tests so we know they still compile. In any case, we can't endlessly drag forward modules we don't even know whether they are used or not. We can't sustain a huge centralized and monolithic repo forever and centralizing reviews in a few people. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This is a library for a websocket client for ESP32 written in pure Lua. This is a completely license-free library I wrote on my own as my contribution back to the nodemcu community.
I'd like to add something to the DOCS as well on this library since I know I go to https://nodemcu.readthedocs.io/en/dev-esp32/ all the time and look for existing libraries, however, none of the pure Lua libraries seem to be in those docs. I'd love to get some in there though because I always forget which Lua libraries are part of the nodemcu ESP32 repo.
dev-esp32
branch rather than formaster
.docs/en/*
.The rationale for this PR is that the NodeMCU ESP32 framework needs a websocket client library.