简体   繁体   English

Arduino是否不支持使用WebSocket协议使用大于65535个字符的消息?

[英]Arduino does not support messages larger than 65535 characters using websocket protocol?

I'm using the following Arduino websocket library , I had a problem when trying to send messages over than 65535 characters, I got handshake fail error. 我正在使用以下Arduino websocket库 ,尝试发送超过65535个字符的消息时遇到问题,出现握手失败错误。
As long as the message doesn't exceeds this length, it worked perfectly 只要消息不超过此长度,它就可以正常工作

There's a note on the main web page of the library that states: 该库的主页上有一条注释指出:

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.

In the client header file named WebSocketClient.h there's the following comment: 在名为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  

I'm using this old library because it is the only one worked for me on my Arduino WIFI shield , I couldn't find other libraries that support WiFi shield since most of the webscket libraries are written for Arduino Eathernet Shield support, which I don't have. 我正在使用这个旧库,因为它是我的Arduino WIFI盾上唯一适合我的库,因为大多数webscket库都是为Arduino Eathernet Shield支持而编写的,所以我找不到其他支持WiFi盾的库。没有。

My Arduino Code is 我的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;

   }

The code above works perfectly, when I uncomment the third send statement in the loop function, I got the handshake failed error. 上面的代码运行完美,当我取消注释循环函数中的第三个send语句时,出现握手失败错误。

-Is it safe to modify the value of MAX_FRAME_LENGTH for the new versions of Arduino board, considering this library is an old one? -考虑到该库是旧库,为新版本的Arduino开发板修改MAX_FRAME_LENGTH的值是否安全?
-Is there any other libraries better than this one that can support websocket on WiFi shield? -是否有其他比该库更好的库可以在WiFi盾上支持websocket?

Any solution or idea will appreciated. 任何解决方案或想法将不胜感激。

Thanks in advance. 提前致谢。

Without having looked at the code of the library it is likely not safe to change the max frame length, because the websocket protocol encodes the payload length differently depending on how long it is: 如果没有查看库的代码,则更改最大帧长度可能是不安全的,因为websocket协议根据有效负载长度的不同而对其进行编码:

Payload length: 7 bits, 7+16 bits, or 7+64 bits. 有效负载长度:7位,7 + 16位或7 + 64位。

The length of the "Payload data", in bytes: if 0-125, that is the payload length. “有效载荷数据”的长度(以字节为单位):如果为0-125,则是有效载荷长度。 If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. 如果为126,则以下解释为16位无符号整数的2个字节为有效载荷长度。 If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length. 如果为127,则以下8个字节被解释为64位无符号整数(最高有效位必须为0)是有效载荷长度。

When the library says it doesn't support payload length above 65535 byte, it likely means that it has no implementation for the 64-bit length encoding. 当库说它不支持65535字节以上的有效载荷长度时,很可能意味着它没有64位长度编码的实现。

After many trials and many times the program behaves very strangely, which drives me crazy, I found the problem is that I'm using too much strings in my program which makes the Arduino-Uno easily runs out of RAM. 经过多次试验和许多次后,程序的行为异常奇怪,这使我发疯,我发现问题是我的程序中使用的字符串过多,这使得Arduino-Uno容易耗尽RAM。

The main reason I got handshake failed error is that the Arduino cannot read the "Sec-WebSocket-Accept" header of the handshake response message (as many other headers also) which I made sure that they are sent, by debugging code on the server. 我收到握手失败错误的主要原因是Arduino无法读取握手响应消息的“ Sec-WebSocket-Accept”标头(也与许多其他标头一样),我通过在服务器上调试代码来确保已发送了它们。

Actually this problem and many other strange behaviors keep happening until I reduce the amount of the memory used during program run. 实际上,这个问题以及许多其他奇怪的行为一直在发生,直到我减少了程序运行期间使用的内存量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM