Closed Perfectmistake closed 3 years ago
Sorry, you can't create secure WebSocket server with Arduino Uno.
use ws://
instead of wss://
Ok, using ws://
, I now obtain a different error message, it seems like the handshake protocol cannot be established:
Traceback (most recent call last):
File "websocketbasictest.py", line 11, in <module>
asyncio.get_event_loop().run_until_complete(test()) # run until
test() is finished
File "/usr/lib64/python3.6/asyncio/base_events.py", line 488, in
run_until_complete
return future.result()
File "websocketbasictest.py", line 5, in test
async with websockets.connect( "ws://198.162.1.177:80/") as websocket:
File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py",
line 604, in __aenter__
return await self
File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py",
line 634, in __await_impl__
extra_headers=protocol.extra_headers,
File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py",
line 397, in handshake
response_headers, available_subprotocols
File "/usr/lib64/python3.6/site-packages/websockets/legacy/client.py",
line 302, in process_subprotocol
raise InvalidHandshake("no subprotocols supported")
websockets.exceptions.InvalidHandshake: no subprotocols supported
Does the WebSocket Server include a header or something similar that must be taken into account when creating a python client?
Show the debug output of your server
How do I do that?
In config.h
, uncomment this:
//#define _DEBUG
//#define _DUMP_HANDSHAKE
//#define _DUMP_FRAME_DATA
//#define _DUMP_HEADER
Then reupload the sketch, try to connect your python client to the Arduino server and show the Serial Monitor output.
Here is what I get in the Serial Monitor:
11:22:16.017 -> [Line #0] GET / HTTP/1.1
11:22:16.050 -> [Line #1] Host: 198.162.1.177
11:22:16.084 -> [Line #2] Upgrade: websocket
11:22:16.117 -> [Line #3] Connection: Upgrade
11:22:16.117 -> [Line #4] Sec-WebSocket-Key: 2psSNoLZdaLVuWeXU117vw==
11:22:16.183 -> [Line #5] Sec-WebSocket-Version: 13
11:22:16.216 -> [Line #6] Sec-WebSocket-Extensions: permessage-deflate;
client_max_window_bits
11:22:16.316 -> [Line #7] User-Agent: Python/3.6 websockets/9.0.1
11:22:16.349 -> [Line #8]
11:22:16.382 -> New client: 198.162.1.21
11:22:16.382 -> TX FRAME : OPCODE=1, FIN=True, RSV=0, PAYLOAD-LEN=26,
MASK=None
11:22:16.449 -> Hello from Arduino server!
11:22:16.482 -> TX BYTES = 28
Your client has been accepted and should receive: Hello from Arduino server
InvalidHandshake("no subprotocols supported")
This is weird because you did not request any subprotocol.
Well from the terminal output posted earlier, its clear that this message is not printing to the terminal, as expected. Do you have any idea why this error could be appearing?
Is it possible for your python client to print a response handshake from a server? I have literally no experience in python, but found this
import logging
logger = logging.getLogger('websockets')
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())
After getting the full log from the client: I get this:
client - state = CONNECTING
client - event = connection_made(<_SelectorSocketTransport fd=6
read=idle write=<idle, bufsize=0>>)
client > GET / HTTP/1.1
client > Headers([('Host', '198.162.1.177'), ('Upgrade', 'websocket'),
('Connection', 'Upgrade'), ('Sec-WebSocket-Key',
'tYLsa0ez8lI7yz0GS6ApyQ=='), ('Sec-WebSocket-Version', '13'),
('Sec-WebSocket-Extensions', 'permessage-deflate;
client_max_window_bits'), ('User-Agent', 'Python/3.6 websockets/9.0.1')])
client - event = data_received(<2 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<3 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<1 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<50 bytes>)
client - event = data_received(<2 bytes>)
client - event = data_received(<26 bytes>)
client - event = data_received(<2 bytes>)
client < HTTP/1.1 101 Switching Protocols
client < Headers([('X-Powered-By', 'mWebSockets'), ('Upgrade',
'websocket'), ('Connection', 'Upgrade'), ('Sec-WebSocket-Accept',
'qoy9WDfSV+a85R93WXPXUe40LWk='), ('Sec-WebSocket-Protocol', '')])
client ! failing CONNECTING WebSocket connection with code 1006
client x half-closing TCP connection
client - event = data_received(<2 bytes>)
client - event = data_received(<26 bytes>)
client - event = eof_received()
client - event = connection_lost(None)
client - state = CLOSED
client x code = 1006, reason = [no reason]
Ok, I know what's wrong. For quick workaround, change this conditional to:
protocol[0] != '\0'
Fantastic!! this now works as expected! One small thing before I close this issue, how would I change the message sent from being text to being data (ie a floating point number). I have tried this:
const char message[] {0.1};
ws.send(WebSocket::DataType::BINARY, message, strlen(message));
But I only get:
b' '
in the terminal, whereas I would like 0.1 to appear.
const char message[]{"0.1"};
Well what about the case where I want to send some value that has been defined previously? for example:
float value;
value = 0.1;
const char message[] {value};
ws.send(WebSocket::DataType::BINARY, message, strlen(message));
This is out of scope of this issue.
Use sprintf
, and read this to save yourself from pain.
I am currently trying to connect my mwebsocket server running on an Arduino Uno (ATmega328P) with a W5500 ethernet shield to a asyncio websockets client in python. The code for the Arduino server is shown below:
And the corresponding python code is shown below:
My aim is to just receive the message "Hello from Arduino server!" every time the client queries the server. Currently, I have an SSL error that keeps appearing whenever I run the python script:
Is there a mismatch between the communications protocol here? Is there something missing that would allow this connection to take place?