无法将ESP32连接到已部署到Heroku的WebSocket服务器 [英] Can't connect ESP32 to websocket server deployed to Heroku

查看:163
本文介绍了无法将ESP32连接到已部署到Heroku的WebSocket服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的ESP32代码,

This is my ESP32 code,

#include <WiFi.h>
#include <WebSocketClient.h>
#include <ArduinoJson.h> 
const char* ssid     = "###";
const char* password = "###";
 
char path[] = "/";
char host[] = "https://hidden-thicket-03510.herokuapp.com";
 
WebSocketClient webSocketClient;
WiFiClient client;

int timer=0;
void connnect(){
   if (client.connect(host,443)) {
    Serial.println("Connected");
  } else {
    Serial.println("Connection failed.");
  }
 
  webSocketClient.path = path;
  webSocketClient.host = host;
  if (webSocketClient.handshake(client)) {
    Serial.println("Handshake successful");
  } else {
    Serial.println("Handshake failed.");
  }
}
void setup() {
  Serial.begin(115200);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  delay(5000);
 
 connnect();

 if (client.connected()) {
   webSocketClient.sendData("Info to be echoed back");
 }
 
}
 
void loop() {
  String data;
  
    if (client.connected()) {

    webSocketClient.getData(data);
    Serial.println(data);
    int data_len = data.length() + 1; 
    char char_array[data_len];
    data.toCharArray(char_array, data_len);
    StaticJsonDocument<1200> doc;

    DeserializationError err=deserializeJson(doc,char_array);

    const char* a=doc["message"];
    
    if (data_len > 1) {
      Serial.print("Received data: ");
      Serial.println(a);
    }
    
  } else {
    Serial.println("Client disconnected.");
    connnect();
  }
 
  delay(3000);
 
}

这是在Heroku上运行的服务器代码

This is the server code running on Heroku

var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
let port =process.env.PORT || 5000;
server.listen(port, function() {
    console.log((new Date()) + ' Server is listening on port 5000');
});

wsServer = new WebSocketServer({
    httpServer: server
});
const clients={}
wsServer.on('request', request=> { 
    var connection = request.accept(null, request.origin);
    console.log((new Date()) + ' Connection accepted.');
    
    const clientId=guid();
    clients[clientId]={
        "connection":connection
    };

    // connection.sendUTF("JSON.stringify(payload)")
    connection.on('open',()=>{console.log("opened")})

    connection.on('message', message => {
        console.log(message);
        var a=JSON.stringify({'message':'sdaed'})
        connection.send(a)
        
    });

    connection.on('close', (reasonCode, description) =>{
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });

    const payload={
        "method":"connect",
        "clientId":clientId
    }
    
    
});



const guid=()=> {
    const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);     
    return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
  }


当我在PC上本地运行服务器时,ESP32连接到服务器.但是,当我将服务器部署到Heroku并尝试连接ESP32握手时,会失败.这是我得到的串行监视器上的输出

When I run the server locally on my PC, ESP32 connects to the server. But when I deploy my server to Heroku and try to connect the ESP32 handshake fail occurs. This is the output on the serial monitor I get

Connected
Waiting...
Waiting...
Waiting...
Handshake failed.
Client disconnected.
Connected
Waiting...
Waiting...
Waiting...
Handshake failed.
Client disconnected.
Connected
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
Handshake failed.

部署到服务器没有问题,因为当我使用nodejs websocket客户端(例如来自存储库)时,它成功连接到已部署的Heroku服务器.我曾尝试将端口号更改为80,并在Arduino脚本上使用"http://hidden-thicket-03510.herokuapp.com",但仍然无法正常工作.

There is no problem with the deployment to server because when I use a nodejs websocket client(example from the repo) it successfully connects to the deployed Heroku server. I have tried changing port number to 80 and using 'http://hidden-thicket-03510.herokuapp.com' on the Arduino script, but it still didn't work.

为什么我的ESP32可以连接到本地运行的服务器,但是部署到服务器时却无法连接

Why is my ESP32 able to connect to the locally running server, but not able to connect when deployed to the server

P.S-如果您要对其进行测试,则上述服务器仍在工作.

P.S - the above server is still working if you want to test it out.

任何帮助将不胜感激!

推荐答案

这是因为您要连接到TLS端点,但是WiFiClient类(用于创建基础连接)没有实现TLS.WebSocketClient类希望接收正常工作的数据管道,但会获得必须在其中设置TLS的TCP连接.

That's because you're connecting to a TLS endpoint but the WiFiClient class (which you use to create the underlying connection) does not implement TLS. The WebSocketClient class expects to receive a working data pipe, but instead it gets a TCP connection where TLS must be set up.

Espressif提供了TCP + TLS实现 WiFiClientSecure 因此,请使用它代替WiFiClient.

Espressif has provided a TCP+TLS implementation WiFiClientSecure so use this instead of WiFiClient.

请注意,与花园类桌面操作系统和浏览器不同,ESP默认情况下不包含任何根证书.因此,它无法验证远程服务器,并且将拒绝连接.您必须手动将服务器的证书添加到ESP32项目中-CA,中间或叶(CA可能是最佳选择).有关如何执行此操作的文档位于项目的自述文件中.

Note that unlike garden variety desktop OS-s and browsers, the ESP does not include any root certificates by default. Hence it cannot verify the remote server and will refuse to connect. You have to manually add the server's certificate to your ESP32 project - either the CA, intermediate, or leaf (CA is probably the best choice). Documentation on how to do that is in the project's README.

要获取与您的服务器关联的证书,我使用 openssl :

To get the certificates associated with your server, I use openssl:

openssl s_client -showcerts -connect hidden-thicket-03510.herokuapp.com:443

我看到您的CA证书可能是名为"DigiCert高保证EV根CA"的证书.复制最后一个PEM块(以 ----- BEGIN CERTIFICATE ----- 开始,以 ----- END CERTIFICATE ----- (含))在输出中,将其粘贴到文件"ca.pem"中并按照说明将其添加到您的ESP项目中.

I see that your CA cert is probably the one named "DigiCert High Assurance EV Root CA". Copy the last PEM block (the base64 starting with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE-----, inclusive) in the output, paste it to file "ca.pem" and add this to your ESP project per instructions.

要验证此文件是否为CA证书,请运行

To verify that this file is the CA certificate, run

openssl x509 -in ca.pem -text -noout

输出应包括主题:C = US,O = DigiCert Inc,OU = www.digicert.com,CN = DigiCert高保证EV根CA

这篇关于无法将ESP32连接到已部署到Heroku的WebSocket服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆