2015-04-04 86 views
0

我使用以下Arduino websocket library,当尝试发送超过65535个字符的邮件时出现问题,我收到了握手失败错误。
只要消息没有超过这个长度,它的工作完美使用websocket协议,Arduino不支持大于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屏蔽的库,因为大多数websocket库都是为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上的websocket更好的库?

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

在此先感谢。

回答

0

经过很多次试验和很多次这个程序的行为非常奇怪,这让我发疯,我发现问题是我在我的程序中使用了太多的字符串,这使得Arduino-Uno容易耗尽内存。

我得到握手的主要原因失败的错误是,Arduino无法读取握手响应消息的“Sec-WebSocket-Accept”头文件(与许多其他头文件一样),我通过调试确认它们已发送代码在服务器上。

实际上,这个问题和许多其他奇怪的行为一直在发生,直到我减少程序运行期间使用的内存量。

0

,而不必看着库的代码很可能不是安全的改变最大帧长度,因为websocket protocol编码的有效载荷长度不同,这取决于它有多长:

有效载荷长度:7比特,7 + 16比特或7 + 64比特。

“有效载荷数据”的长度,以字节为单位:if 0-125,即有效载荷长度。如果为126,则以下2个字节解释为16位无符号整数是净荷长度。如果为127,则将以下8个字节解释为64位无符号整数(最高有效位必须为0)是有效负载长度。

当库说它不支持65535字节以上的有效载荷长度时,这可能意味着它没有64位长度编码的实现。