BetaRavener/upy-websocket-server

Can't connect to websocket...

Closed this issue · 14 comments

Hi,

I 'm using ESP32 with newest Micropython and frozen extra modules like:

uasyncio urequests.py websocket_helper.py

I put your files into ESP, and at first I configured connection like:

`import network

ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=b"ESP", authmode=network.AUTH_WPA_WPA2_PSK, password=b"ESPPass")`

I got a message that websocket has been stardet:

Warning: lwip.setsockopt() option not implemented WebSocket started on ws://192.168.4.1:80 Started WebSocket server.

But after that I'm stuck. I can't open http://192.168.4.1/ - nothing happen and after couple minutes I received 192.168.4.1 didn’t send any data. ERR_EMPTY_RESPONSE...

Also when I tried to make some connection on that hos via js > new Websocket, there nothing happen.

Can you tell me what is wrong?

Hi,
there's another open issue where we dealed with the problem that ESP32 didn't have websocket implementation at that time. Because you're getting different error, I guess things have changed.

You're now getting error (in fact just warning) on this or this line. Try commenting them out to see which one causes the warning.

However, if it's the second one, you have a problem, because that one is responsible for setting function that handles new connections. You would have to implement a workaround, something like constant polling that wouldn't block. The reason why it has to be non-blocking is that you want to be able to communicate with already connected clients while also accepting new connections.

The problem is - I'm not sure how you should do it. In desktop python, you would use select.select, but as far as I know, this one is also not implemented in micropython. You would have to be creative and come up with another solution or just use blocking sockets if you only need one connection at a time.

Unfortunately it was that second line :( I'm new in Python world so not everything is clear to me... Maybe I try ESP8266 to manage it. Such a pity, because ESP32 is better to me for my project.

I have found something in documentation that might help you: class Poll. If you create Poll object for your listening socket, you should be able to poll it and know if there's new connection waiting before performing accept() which would block. Same thing reading data from already connected clients.

Unfortunately, because you're new to Python, this might be just little too hard for you right now. If you give me few days, I could try putting together a solution using Poll but I only have ESP8266 to test with so it's not guaranteed to work for you.

@plugowski Well I got lucky and found some time to look into this right now. I've quickly tested new implementation with Poll class and it seems to be working fairly well. Only problem I encountered is when you refresh page too quickly in browser, the connections doesn't have chance to close and server becomes stuck. But this is extreme case and I doubt you'll be doing such thing (the point of websockets is to avoid page refreshes in first place).

You can find new implementation in separate folder. Please, try it out and report any issues :) Thanks.

It seems to be better now, because I'm able to make an connection with websocket, but if I send something (for example open test.html) it looks like server blows up... What is curious I can send requests, but nothing is returned.

http://blog.lugowski.eu/wp-content/uploads/2018/03/Screen-Shot-2018-03-26-at-10.04.52.png

Hm, the exception traceback in your console window points to this line. It tells us that module object is not callable which means it treats websocket at that line as a module, opposed to class that is imported at line 2.

You could try changing few things in ws_connection.py file:

  • on line 2 this from websocket import websocket to this import websocket
  • and then on line 17 rewrite self.ws = websocket(s, True) to self.ws = websocket.websocket(s, True)

That should make it explicit that we are referring to the class and not the module. See if it fixes the problem. If it does, I will change it also here in the repository.

I changed from websocket import websocket to import import websocket before because it throws me an exception:

>>> from websocket import websocket
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name websocket

Maybe I should download some special websocket module?

>>> websocket.websocket()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'websocket'

Well then this means there's still no builtin websocket support on ESP32 micropython port and I don't know if there's any such module at all. You could try looking at links in this forum thread and try to combine (or just use theirs) implementations to get you what you need, but I haven't reviewed these other solutions.

Btw, it's strange that there's module websocket but it doesn't contain websocket class. Could you run this snippet so we can learn what does that ESP32 module support?

import websocket
dir(websocket)

It looks like that:

>>> import websocket
>>> dir(websocket)
['__class__', '__name__', 'wake_reason']

What is funny firmware for ESP32 use the same websocket module as ESP8266:

~/esp32/micropython/ports/esp32   master  find . | grep websocket
./build/genhdr/qstr/@@__@@__extmod__modwebsocket.c.qstr
./build/extmod/modwebsocket.o
./build/extmod/modwebsocket.P
./build/frozen_mpy/uasyncio/websocket
./build/frozen_mpy/uasyncio/websocket/server.mpy
./build/frozen_mpy/websocket_helper.mpy
./modules/uasyncio/websocket
./modules/uasyncio/websocket/server.py
./modules/websocket_helper.py

I went couple commits back with micropython revisions and I found that now I have websocket.websocket... strange :/

So it's working for you? If it does, please link a revision that you used so I can add it to description.

Yes it works now.
I'm using your fix for ESP32 and revision 0d5bccad.

They broke something because both websocket.websocket and i2c (ssd1306 lib) seems to be not working for me in the newest version...

Great, I have updated the readme, thanks. Closing this for now, feel free to reopen if there's a related problem.

I just clean all builds and download newest revision of micropython and it seems to be working now. So revision I mentioned before is not needed anymore for correct working of your websockets :)