BetaRavener/upy-websocket-server

OSError: [Errno 104] ECONNRESET

Closed this issue · 6 comments

HI,
Thank you for this great library.
I have an ESP8266 as the client connecting to a Lora32 as the server. All works as expected for a few minutes until the client throws this exception:

  File "main.py", line 100, in <module>
  File "/lib/uwebsockets/protocol.py", line 231, in send
  File "/lib/uwebsockets/protocol.py", line 150, in write_frame
OSError: [Errno 104] ECONNRESET

I'll try and catch this error and re-open the connection, but do you have any advice to prevent this happening?

Thank you

I tried catching the exception and reconnecting which works for a while before the server eventually returns '503 Too many connection' so it looks like whatever is causing the disconnect is not closing the connection.

So you figured where the exception occurs? That would be helpful for creating fix for this.

But even without knowing where you are catching the exception, you basically need to remove the connection that thrown from _clients list, otherwise it's dangling there and blocking that slot.

Here's my main block of code with my mitigating fix in place, the line it says the error occurs on is actuall the print statement before the websocket.send(). the sleep(60) was previously sleep(2) but it didn't seem to make the error happen less frequently even though it will be using the connection less often.

I have read that the 8266 is unreliable for anything that requires a constant connection so I will also try the ESP32.
I'm still new to python and haven't yet looked at async functions so I'm wondering if the sleep is preventing the network from keeping itself alive.

while True:
	try:
		if get_dht():
			print("readings changed, updating display")
			print('r,' + str(temperature) + ',' + str(humidity))
			websocket.send('r,' + str(temperature) + ',' + str(humidity))
			response = websocket.recv()
			print(response)
		else:
			print("No change")
		sleep(60)
	except OSError:
		print('Attempting reconnect')
		do_connect() 

Uhm, I'm sorry but how exactly is the code using this library? Take a look how to use it in demo script. You want to implement the process method of client to do the reading and sending the value, and then if you want to save power, at the end of the script put (short) sleep in the while loop like you do in your script.

But overall, websockets are meant for "continuous" communication, where you really want some interaction. The whole point is to keep an open persistent communication channel. Obviously, you want to close the connection before going to sleep, because if browser or other client on the other side doesn't get response from sleeping MCU, it's going to close connection.

But then setting up websocket just for one message and then closing it is very inefficient. If all you want to do is to log temperature once a minute, you probably want to send simple HTTP request to server, or in combination with services like https://thingspeak.com/.

Very sorry, I've got the my projects and the libraries mixed up, I'm actually using uwebsockets! Sorry for wasting your time.

As for the use of websockets rather than individual HTTP requests, the code I showed here is just the beginning and we're replicating a solution we wrote in c++ that has bidirectional communication, for example, the server can instruct the connected device to open and close a door or to set automation values. We actually have that hooked up to Alexa so we can also instruct the device with voice commands.
As it happens, we've give up on micropython for various reasons and have switched back to c++ :)

No problem :) Just a side note, thingspeak also supports something they call "Talkback" which can send commands to MCU, so you get bidirectional communication. I was rather pointing out difference that HTTP request are one-off thing, as opposed to websockets which have to be kept alive and open and that becomes problematic when power (e.g. from battery) is limited.

I also am of similar opinion. Python is great for prototyping, trying out sensors etc.. But it's not great for such resource constrained devices, so for battery powered final projects, I'm usually in favor of C++.