You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-IDF环境下Zenoh-Pico无法连接公共服务器问题求助

ESP32-S3 无法连接 Zenoh 公共服务器问题

问题背景

所有CMakeLists.txt配置正常,代码可正常编译,但ESP32-S3始终无法连接Zenoh公共服务器demo.zenoh.io(解析IP:212.71.244.198)。Wi-Fi连接正常且能获取IP,已尝试切换不同移动数据网络,本地测试tcp/212.71.244.198:7447的Pub/Sub功能正常,排除路由器防火墙问题,但仍存在类似防火墙的连接故障。

最小示例代码

#include <stdio.h>
#include <string.h>
#include "nvs_flash.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "zenoh-pico.h"
#include "utils/config.h"
#include "utils/secret.h"
#include "utils/wifi.h"

#define ZENOH_CONNECT_IP "212.71.244.198"

void data_handler(z_loaned_sample_t *sample, void *arg) {
    z_view_string_t keystr;
    z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr);
    
    z_owned_string_t value;
    z_bytes_to_string(z_sample_payload(sample), &value);
    
    ESP_LOGI(TAG, "--> [Subscriber] Received ('%.*s': '%.*s')", 
             (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)),
             (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value)));
    
    z_drop(z_move(value));
}

void app_main(void) {
    configure_system_logging();
    ESP_LOGI(TAG, "--- ZENOH - ESP-IDF PUB/SUB ----");

    // 初始化NVS Flash
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI(TAG, "Wi-Fi init...");
    wifi_init_sta();

    ESP_LOGI(TAG, "Starting Zenoh app in CLIENT mode...");
    z_owned_session_t session;
    z_owned_config_t config;

    while(1) {
        z_config_default(&config);
        zp_config_insert(z_loan_mut(config), Z_CONFIG_MODE_KEY, "client");

        char connect_endpoint[128];
        snprintf(connect_endpoint, sizeof(connect_endpoint), "tcp/%s:7447", ZENOH_CONNECT_IP);
        zp_config_insert(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, connect_endpoint);
        
        ESP_LOGI(TAG, "Opening Zenoh session: %s", connect_endpoint);

        if (z_open(&session, z_move(config), NULL) == Z_OK) {
            ESP_LOGI(TAG, "Zenoh session opened successfully!");
            break; 
        } else {
            ESP_LOGE(TAG, "Zenoh session failed. Retry in 27 sec...");
            vTaskDelay(27000 / portTICK_PERIOD_MS);
        }
    }

    zp_start_read_task(z_loan_mut(session), NULL);
    zp_start_lease_task(z_loan_mut(session), NULL);

    // 发布者
    const char *pub_key_expr = "demo/esp32/ping";
    ESP_LOGI(TAG, "Declare PUBlisher '%s'...", pub_key_expr);
    z_owned_keyexpr_t pub_key;
    z_keyexpr_from_str(&pub_key, pub_key_expr);
    z_owned_publisher_t pub;
    z_declare_publisher(z_loan(session), &pub, z_loan(pub_key), NULL);
    z_drop(z_move(pub_key));
    
    // 订阅者
    const char *sub_key_expr = "demo/esp32/ping";
    ESP_LOGI(TAG, "Declare SUBscriber '%s'...", sub_key_expr);
    z_owned_keyexpr_t sub_key;
    z_keyexpr_from_str(&sub_key, sub_key_expr);
    z_owned_closure_sample_t callback;
    z_closure(&callback, data_handler, NULL, NULL);
    z_owned_subscriber_t sub;
    z_declare_subscriber(z_loan(session), &sub, z_loan(sub_key), z_move(callback), NULL);
    z_drop(z_move(sub_key));
    
    int count = 0;
    char payload_buffer[128];
    while (1) {
        snprintf(payload_buffer, sizeof(payload_buffer), "ESP32 Message #%d", count++);
        ESP_LOGI(TAG, "[Publisher] Sending: '%s'", payload_buffer);
        z_owned_bytes_t payload;
        z_bytes_copy_from_str(&payload, payload_buffer);
        z_publisher_put(z_loan(pub), z_move(payload), NULL);
        
        // 等待23秒后发送下一条消息
        vTaskDelay(23000 / portTICK_PERIOD_MS);
    }
}

错误日志

I (2569) WIFI: got ip:192.168.1.101
I (2569) WIFI: connected to SSID:XXXXXXXXX
I (2569) ZENOH_APP: Starting Zenoh application in CLIENT mode...
I (2579) ZENOH_APP: Opening Zenoh session: tcp/212.71.244.198:7447
E (2579) ZENOH_APP: Zenoh session failed. Retry in 27 sec...

详细ESP日志

OK!
Opening Zenoh Session...D (4345) lwip: udp_bind(ipaddr =
D (4345) lwip: 0.0.0.0
D (4345) lwip: , port = 16452)
D (4345) lwip: udp_bind: bound to
D (4355) lwip: 0.0.0.0
D (4355) lwip: , port 16452)
D (4355) lwip: udp_send
D (4355) lwip: udp_send: added header in given pbuf 0x3fcb46ec
D (4365) lwip: udp_send: sending datagram of length 39
D (4375) lwip: udp_send: UDP packet length 39
D (4375) lwip: udp_send: UDP checksum 0x6c21
D (4375) lwip: udp_send: ip_output_if (,,,,0x11,)
D (4395) wifi:eb is dhcp or dns sport = 16452, dport = 53
D (4435) lwip: udp_input: received datagram of length 55
D (4435) lwip: UDP header:
D (4435) lwip: +-------------------------------+
D (4435) lwip: |        53     |     16452     | (src port, dest port)
D (4435) lwip: +-------------------------------+
D (4445) lwip: |        55     |     0x5c38    | (len, chksum)
D (4455) lwip: +-------------------------------+
D (4455) lwip: udp (
D (4455) lwip: 192.168.1.100
D (4455) lwip: , 16452) <-- (
D (4465) lwip: 192.168.1.1
D (4465) lwip: , 53)
D (4465) lwip: pcb (
D (4465) lwip: 0.0.0.0
D (4475) lwip: , 16452) <-- (
D (4475) lwip: 0.0.0.0
D (4475) lwip: , 0)
D (4475) lwip: pcb (
D (4475) lwip: 0.0.0.0
D (4485) lwip: , 68) <-- (
D (4485) lwip: 0.0.0.0
D (4485) lwip: , 67)
D (4485) lwip: udp_input: calculating checksum
D (4495) lwip: tcp_close: closing in
D (4495) lwip: State: CLOSED
Unable to open session!

排查建议

  • 单独测试TCP连接:在代码中添加独立的TCP客户端逻辑,直接连接212.71.244.198:7447,验证ESP32能否建立基础TCP连接,排除Zenoh库以外的网络问题。
  • 切换连接协议:尝试使用WebSocket协议连接公共服务器,端点格式改为ws/demo.zenoh.io:80,部分网络环境对WebSocket的兼容性更好。
  • 同步系统时间:检查ESP32的系统时间是否正确,若未同步NTP,可能导致连接握手失败(即使使用明文TCP,部分服务依赖时间校验)。
  • 开启Zenoh调试日志:通过编译选项或配置变量开启Zenoh库的详细日志,查看连接失败的具体触发点(如握手超时、协议不兼容等)。

内容的提问来源于stack exchange,提问作者George Violettas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 12:14:52