尽管已建立连接,但 WebSockets 的 InvalidHandshake'不支持子协议'?

问题描述

目前我有一个 WebSockets 服务器在带有 W5500 以太网屏蔽的 Arduino Uno (ATmega328P) 上运行,我正在尝试将它连接到 asyncio websockets python 客户端。 Arduino WebSocket 服务器代码如下:

#include <WebSocketServer.h>
using namespace net;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[]{0xA8,0x61,0x0A,0xAE,0x69,0x13};
IPAddress ip(198,162,1,177);
IPAddress gateway(0,0);
IPAddress DNSserver(0,0);
IPAddress subnet(255,255,0);

constexpr uint16_t port = 80;
WebSocketServer wss{port};

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  
  Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac,ip,DNSserver,gateway,subnet);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry,can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing,no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  wss.onConnection([](WebSocket & ws) {
    const auto protocol = ws.getProtocol(); 
    if (protocol) {
      Serial.print(F("Client protocol: "));
      Serial.println(protocol);
    }

    ws.onMessage([](WebSocket & ws,const WebSocket::DataType dataType,const char *message,uint16_t length) {
      switch (dataType) {
        case WebSocket::DataType::TEXT:
          Serial.print(F("Received: "));
          Serial.println(message);
          break;
        case WebSocket::DataType::BINARY:
          Serial.println(F("Received binary data"));
          break;
      }

      ws.send(dataType,message,length);
    });

    ws.onClose([](WebSocket &,const WebSocket::CloseCode,const char *,uint16_t) {
      Serial.println(F("disconnected"));
    });

    Serial.print(F("New client: "));
    Serial.println(ws.getRemoteIP());

    const char message[] {"Hello from Arduino server!"};
    ws.send(WebSocket::DataType::TEXT,strlen(message));
  });

  wss.begin();
  Serial.println(Ethernet.localIP());
}

void loop() {
  wss.listen();
}

对应的python代码如下:

import asyncio
import websockets

async def test():
    async with websockets.connect( "ws://198.162.1.177:80/") as websocket:
        await websocket.send(str(1.001))
        response = await websocket.recv()
        print(response)
        
 
asyncio.get_event_loop().run_until_complete(test()) # run until test() is finished

目前,当我尝试将 python 脚本连接到 Arduino 服务器时,我得到:

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

如果我检查来自 Arduino 服务器的日志,客户端似乎能够连接到服务器

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

我对错误代码 InvalidHandshake('no subprotocols supported') 感到困惑,因为我没有请求任何子协议。有没有人知道如何解决这个问题?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...