2015-04-04 126 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位長度編碼的實現。