Клиент веб-сокета Arduino CC3000

Я работаю над клиентом веб-сокета arduino с платой Wi-Fi CC3000 от adafruit. Я использовал этот пример веб-сокета в качестве эталона и модифицировал его для работы с платой Wi-Fi cc3000. Я не могу подключиться к echo.websocket.org. Мой код показывает, что клиент не подключен и недоступен для связи после отправки заголовков обновления. Вот ответ серийного монитора для кода:

echo.websocket.org -> Errno: 1
174.129.224.73-------------------------------------
Client connected
Sending websocket upgrade headers
Analyzing response headers
client not connected
client not available

вот скеч Arduino:

#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include <WebSocketClient.h>
#include "utility/debug.h"

// Это контакты прерывания и управления
#define ADAFRUIT_CC3000_IRQ   3  // ДОЛЖЕН быть контакт прерывания!
// Это могут быть любые два вывода
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Использовать аппаратный SPI для остальных контактов
// На UNO SCK = 13, MISO = 12 и MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // вы можете изменить эту тактовую частоту

#define WLAN_SSID       "UNSTOPPABLE"           // не может быть длиннее 32 символов!
#define WLAN_PASS       "8878333344"
// Безопасность может быть WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA или WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define IDLE_TIMEOUT_MS  3000      // Время ожидания (в миллисекундах) без данных
// получено перед закрытием соединения. Если вы знаете сервер
// к которому вы обращаетесь, быстро реагирует, вы можете уменьшить это значение.

// Какую страницу захватить!
#define WEBSITE      "echo.websocket.org"
//#определить ВЕБ-СТРАНИЦУ "/testwifi/index.html"

// Здесь мы определяем максимальную длину кадра в 64 байта. По умолчанию 256.
#define MAX_FRAME_LENGTH 64

// Определите, сколько у вас функций обратного вызова. По умолчанию 1.
#define CALLBACK_FUNCTIONS 1



Adafruit_CC3000_Client www;
WebSocketClient webSocketClient;
/**************************************************************************/
/*!
 @brief  Sets up the HW and the CC3000 module (called automatically
 on startup)
 */
/**************************************************************************/

uint32_t ip;

void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Hello, CC3000!\n")); 

  Serial.print("Free RAM: "); 
  Serial.println(getFreeRam(), DEC);

  /* Initialise the module */
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }

  // Дополнительное сканирование SSID
  // списокSSIDResults();

  Serial.print(F("\nAttempting to connect to ")); 
  Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

  Serial.println(F("Connected!"));

  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100); // Задача: Вставить тайм-аут DHCP!
  }  

  /* Display the IP address DNS, Gateway, etc. */
  while (! displayConnectionDetails()) {
    delay(1000);
  }

  ip = 0;
  // Попробуйте найти IP-адрес веб-сайта
  Serial.print(WEBSITE); 
  Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }

  cc3000.printIPdotsRev(ip);

  // Необязательно: проведите пинг-тест на веб-сайте
  /*
  Serial.print(F("\n\rPinging ")); cc3000.printIPdotsRev(ip); Serial.print("...");  
   replies = cc3000.ping(ip, 5);
   Serial.print(replies); Serial.println(F(" replies"));
   */

  /* Try connecting to the website.
   Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read.
   */
  www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    /*    www.fastrprint(F("GET "));
     www.fastrprint(WEBPAGE);
     www.fastrprint(F(" HTTP/1.1\r\n"));
     www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
     www.fastrprint(F("\r\n"));
     www.println();*/
  } 
  else {
    Serial.println(F("Connection failed"));    
    return;
  }

  Serial.println(F("-------------------------------------"));

  /* Read data until either the connection is closed, or the idle timeout is reached. */
  /*  unsigned long lastRead = millis();
   while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
   while (www.available()) {
   char c = www.read();
   Serial.print(c);
   lastRead = millis();
   }
   }
   www.close();
   Serial.println(F("-------------------------------------"));*/

  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
  /* the next time your try to connect ... */
  /*  Serial.println(F("\n\nDisconnecting"));
   cc3000.disconnect();*/
  // Рукопожатие с сервером
  webSocketClient.path = "/";
  webSocketClient.host = WEBSITE;

  if (webSocketClient.handshake(www)) {
    Serial.println("Handshake successful");
  } 
  else {
    Serial.println("Handshake failed.");
    while(1) {
      // Зависание при сбое
    }  
  }  
}

void loop(void)
{
  String data; 
  if (www.connected()) {

    /*   data = webSocketClient.getData();

     if (data.length() > 0) {
     Serial.print("Received data: ");
     Serial.println(data);
     }*/

    // фиксируем значение аналога 1, отправляем его дальше
    pinMode(1, INPUT);
    data = String(analogRead(1));

    webSocketClient.sendData(data);

  } 
  else {

    Serial.println("Client disconnected.");
    while (1) {
      // Зависание при отключении.
    }
  }

  // ждем, пока клиент полностью отключится
  delay(3000);
}

Если кто-нибудь может указать мне, где я ошибаюсь, это было бы очень полезно. Я взял справочный код из brandenhall/Arduino-Websocket.

, 👍1

Обсуждение

Не могли бы вы добавить обнюхивание Wireshark того, что происходит?, @Lesto

Спасибо за ответ, я не понимаю, что делать с wirehark. В моем случае мой клиентский код не взаимодействует с эхо-сервером. Поскольку я поставил отладочную печать, она отключилась от клиента после отправки заголовка обновления., @Taher Kawantwala

Затем распечатайте ответ от сервера. А также то, что вы отправляете. (Это то, что делает Wireshark), @Lesto

вот проблема в том, что я ничего не получаю с сервера. Мой клиент отключился от сервера после отправки заголовков Upgrade. вот почему в wireshark я ничего не получаю от сервера, я так думаю., @Taher Kawantwala

Затем опубликуйте то, что вы отправляете!, @Lesto


1 ответ


1

проблема в том, что я ничего не получаю с сервера. Мой клиент отключился от сервера после отправки заголовков Upgrade. вот почему в wire-shark я ничего не получаю от сервера, я так думаю. вот код, который выполняет рукопожатие с сервером. Проблема в том, что я ничего не получаю от сервера. Мой клиент отключился от сервера после отправки заголовков Upgrade. вот почему в Wire Shark я ничего не получаю от сервера, я так думаю. вот код, который выполняет рукопожатие с сервером:

bool WebSocketClient::analyzeRequest() { темп строки; внутренний укус; bool foundupgrade = ложь; беззнаковый длинный ключ [2]; Строка serverKey; char keyStart[17]; char b64Key[25]; Строковый ключ = "------------------------"; randomSeed (аналоговое чтение (0)); for (целое i=0; i<16; ++i) { keyStart[i] = (char)random(1, 256); } base64_encode (b64Key, keyStart, 16); for (целое i=0; i<24; ++i) { ключ[i] = b64Key[i]; } Serial.println(F("Отправка заголовков обновления вебсокета")); socket_client->print(F("GET")); socket_client-> печать (путь); socket_client->print(F(" HTTP/1.1\r\n")); socket_client->print(F("Обновление: websocket\r\n")); socket_client->print(F("Соединение: Обновление\r\n")); socket_client->print(F("Хост: ")); socket_client-> печать (хост); socket_client-> печать (CRLF); socket_client->print(F("Sec-WebSocket-Key: ")); socket_client-> печать (ключ); socket_client-> печать (CRLF); socket_client->print(F("Sec-WebSocket-Protocol: ")); socket_client-> печать (протокол); socket_client-> печать (CRLF); socket_client->print(F("Sec-WebSocket-Version: 13\r\n")); socket_client-> печать (CRLF); Serial.println(F("Анализ заголовков ответа")); // здесь он отключился в то время как (socket_client->connected() && !socket_client-> available()) { delay(100); Serial.println("Ожидание..."); } // TODO: Более надежное извлечение строк в то время как ((укус = socket_client->read()) != -1) { temp += (символ) укус; если ((символ) укусить == '\n') { #ifdef ОТЛАДКА Serial.print("Получен заголовок: " + temp); #endif if (!foundupgrade && temp.startsWith("Обновление: веб-сокет")) { найденное обновление = истина; } иначе если (temp.startsWith("Sec-WebSocket-Accept: ")) { serverKey = temp.substring(22,temp.length() - 2); // Не сохранять последний CR+LF } темп = ""; } если (!socket_client->доступно()) { delay(20); } } ключ += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; uint8_t *хэш; символьный результат[21]; char b64Result[30]; Ша1.инит(); Sha1.print(ключ); хэш = Sha1.result(); for (целое i=0; i<20; ++i) { результат[i] = (char)хэш[i]; } результат[20] = '\0'; base64_encode (b64Result, результат, 20); // если ключи совпадают, можно начинать вернуть serverKey.equals (String (b64Result));

,