Esp8266 MicroPython中使用轮询的非阻塞服务器套接字问题
我正在尝试组装一个简单的温度计,它可以提供OLED显示屏上的温度,也可以通过使用MicroPython的ESP8266上的http请求提供温度 轮询器对象用于防止websocket阻塞环路,以便更新测量和OLED显示Esp8266 MicroPython中使用轮询的非阻塞服务器套接字问题,esp8266,micropython,usocket,Esp8266,Micropython,Usocket,我正在尝试组装一个简单的温度计,它可以提供OLED显示屏上的温度,也可以通过使用MicroPython的ESP8266上的http请求提供温度 轮询器对象用于防止websocket阻塞环路,以便更新测量和OLED显示 #CREATE SOCKET serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serverSocket.bind(('', 80)) serverSocket.listen(5) #REGISTER
#CREATE SOCKET
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(('', 80))
serverSocket.listen(5)
#REGISTER SOCKET TO THE POLLER
pollerObject = select.poll()
pollerObject.register(serverSocket, select.POLLIN)
#PERFORM FIRST MEASUREMENT AT STARTUP
last_meas_time = startup_time
sensor_readings = read_sensor()
print(sensor_readings)
display.display_measurement(str(temp),str(hum))
#LOOP FOREVER
while True:
#ONE MEASUREMENT UPDATE EVERY 30s
if(time.time() - last_meas_time >= 30):
sensor_readings = read_sensor()
print(sensor_readings)
display.display_measurement(str(temp),str(hum))
last_meas_time = time.time()
#WAIT UP TO 10s FOR INCOMING CONNECTIONS
fdVsEvent = pollerObject.poll(10000)
for descriptor, Event in fdVsEvent:
print()
print("Got an incoming connection request")
print("Start processing")
# Do accept() on server socket or read from a client socket
conn, addr = serverSocket.accept()
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
print('Content = %s' % str(request))
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
一段时间以来,它似乎运行良好,但我发现它存在两个问题,非常感谢您的帮助:
即使我只连接到它一次,2或3个请求在shell终端中显示为已接收,如下所示。为什么会发生这种情况?我该如何解决?浏览器是否可以等待足够长的时间来发送第二个或第三个请求?
谢谢
即使我只连接到它一次,2或3个请求在shell终端中显示为已接收,如下所示。为什么会发生这种情况?我该如何解决?浏览器是否可以等待足够长的时间来发送第二个或第三个请求
这取决于浏览器如何连接到服务器。浏览器可能正在查找多个请求,或者浏览器具有连接到服务器的套接字的超时值。我没有任何网络知识,但它看起来像两个不同的信息请求。这些信息是如何处理的,应该传递到网页上。看起来您发送的是整个网页,而不是它要查找的特定内容
经过长时间运行后,我将无法再连接到它,因为它将不会响应。我的方法有什么明显的问题吗
可能发生的情况是socket.sendall阻止创建任何新套接字。另外请注意,即使已正确关闭套接字,套接字仍可能有数据要发送。它已被标记为关闭,但操作系统可能尚未关闭它
通过使用select.poll,您的思路是正确的。乍一看,似乎使用pollerObject select.poll注册serverSocket可以处理将来的连接。事实并非如此。您只向pollerObject注册了一个套接字。severSocket正在从浏览器获取传入连接的select.POLLIN事件。您需要一种将serverSocket创建的新套接字添加/注册到pollerObject的方法,以便为其他套接字提供服务
现在,在micropython中尝试做的最好的示例是制作类似于中选择器示例的东西
通常,您不必担心用socket.send填充套接字传输缓冲区,但您应该处理它。现在,我会在socket.sendall之前和之后放置一些调试打印,因为这将阻止/重试,直到发送所有数据。如果并非所有数据都已发送,则必须为写准备事件注册套接字,并传递需要发送的其余数据。这有点复杂
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59160)
Content = b''
Traceback (most recent call last):
File "main.py", line 104, in
OSError: [Errno 104] ECONNRESET
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>>
您在上面遇到的问题是,您的套接字连接可能已超时。TCP正在让您知道连接已过期。您应该使用try-except-else子句来处理此问题
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59158)
Content = b'GET / HTTP/1.1\r\nHost: 192.168.1.74\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nDNT: 1\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,sv;q=0.5\r\n\r\n'
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59157)
Content = b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.1.74\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\r\nDNT: 1\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://192.168.1.74/\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: pt-BR,pt;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,sv;q=0.5\r\n\r\n'
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59160)
Content = b''
Traceback (most recent call last):
File "main.py", line 104, in
OSError: [Errno 104] ECONNRESET
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>>
conn.sendall(response)
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
conn, addr = sock.accept() # Should be ready
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000) # Should be ready
if data:
print('echoing', repr(data), 'to', conn)
conn.send(data) # Hope it won't block
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
Got an incoming connection request
Start processing
Got a connection from ('192.168.1.64', 59160)
Content = b''
Traceback (most recent call last):
File "main.py", line 104, in
OSError: [Errno 104] ECONNRESET
MicroPython v1.13 on 2020-09-11; ESP module with ESP8266
Type "help()" for more information.
>>>