You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
websockets work now
This commit is contained in:
@@ -3,6 +3,13 @@ import ssl
|
||||
import ubinascii
|
||||
from websocket import websocket
|
||||
import time
|
||||
import select
|
||||
import gc
|
||||
|
||||
# Log memory usage
|
||||
def log_memory():
|
||||
gc.collect()
|
||||
print('Free memory:', gc.mem_free())
|
||||
|
||||
# Connect to Wi-Fi (disabled as per your code)
|
||||
if False:
|
||||
@@ -14,14 +21,13 @@ if False:
|
||||
print('Connected:', wlan.ifconfig())
|
||||
|
||||
# Resolve hostname
|
||||
# Option 1: echo.websocket.events (unreliable)
|
||||
host = 'echo.websocket.events'
|
||||
# Option 1: ws.postman-echo.com (recommended for reliable echo)
|
||||
host = 'ws.postman-echo.com'
|
||||
port = 443
|
||||
handshake_path = '/'
|
||||
# Option 2: ws.postman-echo.com (recommended for testing)
|
||||
# host = 'ws.postman-echo.com'
|
||||
# port = 443
|
||||
# handshake_path = '/raw'
|
||||
handshake_path = '/raw'
|
||||
# Option 2: echo.websocket.events (unreliable)
|
||||
# host = 'echo.websocket.events'
|
||||
# handshake_path = '/'
|
||||
|
||||
try:
|
||||
addr_info = socket.getaddrinfo(host, port)[0][-1]
|
||||
@@ -44,10 +50,12 @@ except Exception as e:
|
||||
try:
|
||||
ssl_sock = ssl.wrap_socket(sock, server_hostname=host)
|
||||
print('SSL connection established')
|
||||
print('SSL cipher:', ssl_sock.cipher())
|
||||
except Exception as e:
|
||||
print('SSL wrap failed:', e)
|
||||
sock.close()
|
||||
raise
|
||||
log_memory()
|
||||
|
||||
# Set socket to non-blocking
|
||||
ssl_sock.setblocking(False)
|
||||
@@ -74,15 +82,29 @@ except Exception as e:
|
||||
print('Failed to send handshake:', e)
|
||||
ssl_sock.close()
|
||||
raise
|
||||
log_memory()
|
||||
|
||||
# Read HTTP response until \r\n\r\n (minimize reading)
|
||||
# Read HTTP response until \r\n\r\n
|
||||
response_bytes = bytearray()
|
||||
max_read = 1024
|
||||
read_timeout = 2
|
||||
read_timeout = 5 # Increased to 5s for server response
|
||||
start_time = time.time()
|
||||
poller = select.poll()
|
||||
poller.register(ssl_sock, select.POLLIN)
|
||||
while len(response_bytes) < max_read:
|
||||
events = poller.poll(100) # Wait 100ms
|
||||
print('Poll events:', events)
|
||||
if not events:
|
||||
if time.time() - start_time > read_timeout:
|
||||
print('Read timeout reached')
|
||||
break
|
||||
continue
|
||||
try:
|
||||
chunk = ssl_sock.read(128)
|
||||
print('Read attempt, chunk:', chunk)
|
||||
if chunk is None:
|
||||
print('Read returned None, continuing to poll')
|
||||
continue
|
||||
if not chunk:
|
||||
print('No more data received (EOF)')
|
||||
break
|
||||
@@ -91,7 +113,6 @@ while len(response_bytes) < max_read:
|
||||
print('Total bytes received:', len(response_bytes))
|
||||
if b'\r\n\r\n' in response_bytes:
|
||||
print('End of HTTP headers detected')
|
||||
# Decode and verify HTTP response immediately
|
||||
http_end = response_bytes.find(b'\r\n\r\n') + 4
|
||||
if http_end < 4:
|
||||
ssl_sock.close()
|
||||
@@ -110,15 +131,12 @@ while len(response_bytes) < max_read:
|
||||
print('Handshake response:', response)
|
||||
ssl_sock.close()
|
||||
raise Exception('Handshake failed')
|
||||
# Stop reading to leave WebSocket frame in socket buffer
|
||||
print('Stopping read to preserve WebSocket frame')
|
||||
break
|
||||
except Exception as e:
|
||||
print('Error reading chunk:', e)
|
||||
break
|
||||
if time.time() - start_time > read_timeout:
|
||||
print('Read timeout reached')
|
||||
break
|
||||
log_memory()
|
||||
|
||||
# Create WebSocket object
|
||||
try:
|
||||
@@ -128,8 +146,9 @@ except Exception as e:
|
||||
print('Failed to create WebSocket object:', e)
|
||||
ssl_sock.close()
|
||||
raise
|
||||
log_memory()
|
||||
|
||||
# Send and receive data with retries
|
||||
# Send and receive data with polling
|
||||
try:
|
||||
bytes_written = ws.write('Hello, Secure WebSocket!')
|
||||
print('Sent message, bytes written:', bytes_written)
|
||||
@@ -138,23 +157,29 @@ except Exception as e:
|
||||
ws.close()
|
||||
raise
|
||||
|
||||
# Try reading multiple times to catch initial message or echo
|
||||
max_attempts = 5
|
||||
read_timeout = 1 # Short timeout per read
|
||||
# Poll for data with retries
|
||||
max_attempts = 10 # Increased retries
|
||||
poll_timeout = 100 # 100ms per poll
|
||||
start_time = time.time()
|
||||
for attempt in range(max_attempts):
|
||||
events = poller.poll(poll_timeout)
|
||||
print('Read poll attempt', attempt + 1, 'events:', events)
|
||||
if not events:
|
||||
print('Read attempt', attempt + 1, 'no data available')
|
||||
if time.time() - start_time > 2: # 2s total timeout
|
||||
print('Read timeout reached')
|
||||
break
|
||||
continue
|
||||
try:
|
||||
data = ws.read(1024)
|
||||
print('Read attempt', attempt + 1, 'received:', data)
|
||||
if data:
|
||||
break
|
||||
time.sleep(0.5) # Wait briefly before retrying
|
||||
except Exception as e:
|
||||
print('Read attempt', attempt + 1, 'error:', e)
|
||||
time.sleep(0.5)
|
||||
if time.time() - start_time > read_timeout:
|
||||
print('Read timeout reached')
|
||||
break
|
||||
time.sleep(0.1)
|
||||
|
||||
# Close connection
|
||||
ws.close()
|
||||
print('Connection closed')
|
||||
log_memory()
|
||||
|
||||
Reference in New Issue
Block a user