c++ - Arduino 不支持使用 websocket 协议(protocol)的大于 65535 个字符的消息?

标签 c++ c websocket arduino

我正在使用以下Arduino websocket library ,我在尝试发送超过 65535 个字符的消息时遇到问题,出现握手失败错误。
只要消息不超过这个长度,它就可以正常工作

图书馆主页上有一条注释,指出:

Because of limitations of the current Arduino platform (Uno at the time of this writing),   
 this library does not support messages larger than 65535 characters.   
 In addition, this library only supports single-frame text frames.   
 It currently does not recognize continuation frames, binary frames, or ping/pong frames.

在名为 WebSocketClient.h 的客户端头文件中,有以下注释:

// Don't allow the client to send big frames of data. This will flood the arduino memory and might even crash it.  
    #ifndef MAX_FRAME_LENGTH
    #define MAX_FRAME_LENGTH 256
    #endif  

我正在使用这个旧库,因为它是我的 Arduino WIFI shield 上唯一对我有用的库。 ,我找不到其他支持 WiFi Shield 的库,因为大多数 webscket 库都是为 Arduino Eathernet Shield 编写的。支持,我没有。

我的 Arduino 代码是

/*DS18 Libs*/
#include <dht.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/*Websocket Libs*/
#include <WebSocketServer.h>
#include <WebSocketClient.h>
#include <sha1.h>
#include <MD5.h>
#include <global.h>
#include <Base64.h>
#include <SPI.h>
#include <WiFiUdp.h>
#include <WiFiServer.h>
#include <WiFiClient.h>
#include <WiFi.h>
#include <string.h>

char ssid[] = "AMM";
char pass[] = "027274792";
int status = WL_IDLE_STATUS;
IPAddress server(192, 168, 1, 3);
WiFiClient WiFiclient;
WebSocketClient WSclient;

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)  

OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

//Humidture
dht DHT;
#define DHT11_PIN 4

void setup()
{
   Serial.begin(9600);
    while (!Serial) {
          ; // wait for serial port to connect. Needed for Leonardo only
}

 //check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
}

// attempt to connect to Wifi network:
while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:    
    status = WiFi.begin(ssid, pass);
}

// you're connected now, so print out the data:
Serial.print("You're connected to the network");

/* Connect to the websocket server*/
if (WiFiclient.connect(server, 8080)) {
    Serial.println("Connected");
}
else {
    Serial.println("Connection failed.");
    while (1) {
        // Hang on failure
    }
}

// Handshake with the server
WSclient.path = "/MyServer/endpoint/testtest/device/d6220ae7-caa9-48b5-92db-630c4c296ec4";
WSclient.host = "192.168.1.3:8080";

if (WSclient.handshake(WiFiclient)) {
    Serial.println("Handshake successful");
}
else {
    Serial.println("Handshake failed.");
    while (1) {
        // Hang on failure
    }
}

/*DS18*/
sensors.begin();
 }

void loop()
{   
     WSclient.sendData("{\"service_code\":\"89c4da72-a561-47db-bf62-8e63f8c4bbf0\",\"data\":[" + getHumidtureValue() + "],\"service_type\":\"TemperatureHumidityAnalysis\"}");
     WSclient.sendData("{\"service_code\":\"bdc0f984-6550-4712-881f-b09071da5a73\",\"data\":" + getCBodyTempretureValue() + ",\"service_type\":\"TemperatureGaugeMonitor\"}");
     //line-3 commented WSclient.sendData("{\"service_code\":\"8c212432-a86e-4c18-a956-9dc0dbb648d4\",\"data\":[" + getHumidtureValue() + "],\"service_type\":\"HumidityGaugeMonitor\"}");
}

 String getCBodyTempretureValue()
 {
     sensors.requestTemperatures(); // Send the command to get temperatures
     char charVal[10];
     return dtostrf(sensors.getTempCByIndex(0), 4, 2, charVal);
 }

 String getHumidtureValue()
 {
      String str = "";
      for (int i = 0; i < 2; i++)
      {
         int chk = DHT.read11(DHT11_PIN);
         switch (chk)
         {
            case DHTLIB_OK:
               Serial.println("OK,\t");
               break;
            case DHTLIB_ERROR_CHECKSUM:
               Serial.println("Checksum error,\t");
               break;
            case DHTLIB_ERROR_TIMEOUT:
               Serial.println("Time out error,\t");
               break;
             default:
               Serial.println("Unknown error,\t");
               break;
           }

           char charVal[10];
           double tempF = (DHT.temperature * 9) / 5 + 32;
           str = dtostrf(tempF, 3, 1, charVal);
           str = str + "," + dtostrf(DHT.humidity, 3, 1, charVal);
           Serial.println(str);
           delay(200);
     }
     return str;

   }

上面的代码工作正常,当我取消注释循环函数中的第三个发送语句时,出现握手失败错误。

-考虑到这个库是旧的,修改新版本 Arduino 板的 MAX_FRAME_LENGTH 值是否安全?
- 有没有比这个更好的库可以在 WiFi shield 上支持 websocket ?

任何解决方案或想法将不胜感激。

提前致谢。

最佳答案

如果没有查看库的代码,更改最大帧长度可能不安全,因为 websocket protocol根据有效负载的长度对有效负载长度进行不同的编码:

Payload length: 7 bits, 7+16 bits, or 7+64 bits.

The length of the "Payload data", in bytes: if 0-125, that is the payload length. If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length.

当该库表示不支持超过 65535 字节的有效负载长度时,这可能意味着它没有实现 64 位长度编码。

关于c++ - Arduino 不支持使用 websocket 协议(protocol)的大于 65535 个字符的消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29444755/

相关文章:

c++ - 生成 0 到 n 范围内的随机数,其中 n 可以 > RAND_MAX

c - 如何在 C 代码中包含存档文件

ruby-on-rails - 到 'ws://example.com/cable' 的 WebSocket 连接失败 : Unexpected response code: 404

c++ - 获取所有可能的组合数

c++ - fatal error : 'stdafx.h' file not found

c++ - 防止在 Visual Studio 调试期间进入 "memory"

c - C中的for循环错误

c++ - 在 C++ 中初始化派生类参数

jsf - f :websocket stops working in JSF 2. 3 在 Wildfly 上重新部署应用程序后

运行 websockets secure (WSS) 的 node.js 服务器上的 SSL 证书