使用IP将esp8266上的websocket连接到本地服务器

问题描述 投票:0回答:1

我开始从事一个小型“智能家居”项目,以了解嵌入式开发和 Rust。我有

  • 带有 DHT 的 ESP8266,用于测量湿度和温度,用 C++ 编写
  • 用 Rust 编写的服务器,有一个 FE 非常小的路由(参见下一点)以及用于 websocket 发送和接收数据的路由
  • 一个小的 FE,目前是几行 HTML 和 JS,连接到上述服务器并读取传感器发送的数据

服务器的“生产”版本是托管的,并且有一个域名,我可以用它来连接到它。单片机和FE可以使用域名分别使用wss和https连接。

我还想要一个可以在本地使用来调试的设置。这意味着服务器在 127.0.0.1 上运行,并且微控制器可以连接到它。最后,我想要一个构建标志,我可以设置它来定义正在构建的内容。 理想情况下,本地设置还应具有 SSL 加密,以更好地接近“生产”设置。我已经有一个可以使用的本地创建的证书,但作为第一步,简单的连接就足够了。

我的问题是我无法让微控制器连接到在 127.0.0.1 上运行的本地服务器

我将 PlatformIO 与以下库一起使用:

  • adafruit/DHT 传感器库@^1.4.6
  • adafruit/Adafruit 统一传感器@^1.1.14
  • gilmaimon/ArduinoWebsockets@^0.5.3

这是微控制器的代码:

#include <Arduino.h>
#include <DHT.h>
#include <DHT_U.h>
#include <ESP8266WiFi.h>
#include <ArduinoWebsockets.h>

#define DHTTYPE    DHT11
#define DHTPIN 2

DHT_Unified dht(DHTPIN, DHTTYPE);

const char* const public_address = "wss://mydomain.com/sensor/";
const char public_fingerprint[] PROGMEM = "<fingerprint>";

const char* const local_address = "wss://127.0.0.1:9231/sensor/";
const char local_fingerprint[] PROGMEM = "<fingerprint>";

const bool IS_LOCAL_SETUP = true; // for now simple bool switch

bool connected = false;

using namespace websockets;
WebsocketsClient client;

void onMessageCallback(WebsocketsMessage message) {
  // ...
}

void onEventsCallback(WebsocketsEvent event, String data) {
  // ...
}

void setup() {
  Serial.begin(115200);

  while (!Serial) {
    ; // Wait for serial
  }

  WiFi.mode(WIFI_STA);
  int count = WiFi.scanNetworks(false, true, 0, NULL);
  Serial.printf("Number of wifi networks: %d\n", count);

  String ssid = "<ssid>";

  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, "<password>");

  while (WiFi.status() != WL_CONNECTED && WiFi.status() != WL_CONNECT_FAILED)
  {
    delay(750);
    Serial.print('*');
  }

  Serial.println();

  if (WiFi.status() == WL_CONNECT_FAILED)
  {
    Serial.println("Error when connecting to wifi");
    return;
  }

  Serial.println("WiFi connection successful");
  Serial.println(WiFi.localIP());

  // run callback when messages are received
  client.onMessage(onMessageCallback);
  
  // run callback when events are occuring
  client.onEvent(onEventsCallback);

  if (IS_LOCAL_SETUP) {
    client.setFingerprint(local_fingerprint);
  } else {
    client.setFingerprint(public_fingerprint);
  }

  bool res;
  // Connect to server
  if (IS_LOCAL_SETUP) {
    res = client.connect(local_address);
  } else {
    res = client.connect(public_address);
  }
  if (!res) {
    Serial.println("Failed to connect");
    return;
  }

  connected = true;

  dht.begin();
  // printing sensor info
}

void loop() {
  delay(2000);

  if (!connected) {
    return;
  }

  client.poll();

  // Get temperature event and print its value.
  // ...

  // Send a message
  std::string msg = "...";
  bool res = client.send(msg.c_str());
  if (!res) {
    Serial.println("Failed to send message");
    return;  
  }
}

我设置了定义

DEBUG_ESP_SSL
DEBUG_ESP_PORT
以从 WSP8266WiFi 库获取更多日志,但看不到任何有用的内容:

SDK:2.2.2-dev(38a443e)/Core:3.1.2=30102000/lwIP:STABLE-2_1_3_RELEASE/glue:1.2-65-g06164fb/BearSSL:b024386
fpm close 1
mode : sta(c4:5b:be:55:92:4d)
add if0
scandone

**scandone
state: 0 -> 2 (b0)
*state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 17
cnt

connected with <SSID>, channel 6
dhcp client start...
ip:<ip>,mask:255.255.255.0,gw:<>

Setting fingerprint
Creating client
BSSL:connect: Unable to connect TCP socket

pm open,type:2 0

无论如何,

client.connect
调用都会返回
0
。从日志中我可以看到调用
WiFiClient::connect
时连接失败,尽管我不知道为什么。

我尝试过的:

  • 在绝望的尝试中使用
    localhost
    代替IP,因为我认为也许不可能直接传递IP - 没有区别
  • wss
    转换为
    ws
    并删除指纹 - 没有区别

我是否遗漏了一些明显的东西?我读到防火墙可能是一个问题,但由于我可以访问 FE 并且 FE 可以创建到本地服务器的 Websocket 连接,我怀疑这就是问题所在。

如果您需要服务器代码,请告诉我。

非常感谢您的帮助和提示

websocket esp8266 platformio esp8266wifi
1个回答
0
投票

无法连接到127.0.0.1,因为127.0.0.1是“环回”接口;它是“同一设备”的缩写。无法从运行服务器的设备之外的任何地方访问它。 “localhost”是完全相同的东西。

您需要使用运行服务器的设备的网络接口之一的 IP 地址。您需要将服务器配置为在启动时绑定到该 IP 地址,而不仅仅是 127.0.0.1。如何找到 IP 地址取决于您的服务器运行的操作系统。

© www.soinside.com 2019 - 2024. All rights reserved.