Symfony部署Hostinger后与ESP8266通信超时问题求助
问题描述
我开发了一个Symfony项目,需要通过HTTP请求与ESP8266设备通信。本地WAMP环境下运行正常,Postman测试也没问题,但部署到Hostinger主机后,一直出现超时错误。我和ESP8266在同一WiFi网络,试过用GuzzleHttp\Client也没解决问题。
Symfony 代码
#[IsGranted('ROLE_USER')] #[Route('/activateBottle/{id}', name: 'app_activateBottle')] public function activateBottle(WineGame $wineGame) { $client = HttpClient::create(); try { $response = $client->request('GET', "https://" . $wineGame->getIpBottle() . "/activeBottle", [ 'timeout' => 30.0 ]); if ($response->getStatusCode() === 200) { $this->addFlash( 'success', "La bouteille sonne" ); } else { $this->addFlash( 'error', "Erreur lors de la connexion à la bouteille" ); } } catch (TransportExceptionInterface $e) { $this->addFlash( 'error', "Erreur lors de la connexion à la bouteille :" . $e ); } return $this->redirectToRoute('app_wineGame', ['id' => $wineGame->getId()]); }
ESP8266 代码
#include <ESP8266WebServer.h> #include <ESP8266HTTPClient.h> #include <ESP8266WiFi.h> #include <ArduinoJson.h> // 网络连接信息 const char * SSID = "XXXX"; const char * PASSWORD = "XXXX"; // Web服务器对象 ESP8266WebServer serverWeb(80); // Web服务器回调函数 void activeBottle(){ serverWeb.send(200, "text/html", "activeBottle"); Serial.println("激活成功"); } void setup() { Serial.begin(115200); Serial.println(""); // 设置WiFi模式为客户端 WiFi.mode(WIFI_STA); // 启动WiFi连接 WiFi.begin(SSID, PASSWORD); Serial.print("连接中..."); while(WiFi.status() != WL_CONNECTED){ Serial.print("."); delay(500); } Serial.println("\n"); // 配置Web服务器路由 serverWeb.on("/activeBottle", activeBottle); serverWeb.begin(); } void loop() { if(WiFi.isConnected()){ serverWeb.handleClient(); } }
错误信息
Symfony\Component\HttpClient\Exception\TimeoutException: Idle timeout reached for "http://192.168.1.43/activeBottle". in /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-client/Chunk/ErrorChunk.php:56 Stack trace: #0 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-client/Response/CommonResponseTrait.php(141): Symfony\Component\HttpClient\Chunk\ErrorChunk->isFirst() #1 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-client/Response/TransportResponseTrait.php(52): Symfony\Component\HttpClient\Response\CurlResponse::initialize() #2 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/src/Controller/UserController.php(141): Symfony\Component\HttpClient\Response\CurlResponse->getStatusCode() #3 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-kernel/HttpKernel.php(163): App\Controller\UserController->activateBottle() #4 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-kernel/HttpKernel.php(74): Symfony\Component\HttpKernel\HttpKernel->handleRaw() #5 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/http-kernel/Kernel.php(184): Symfony\Component\HttpKernel\HttpKernel->handle() #6 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php(35): Symfony\Component\HttpKernel\Kernel->handle() #7 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/vendor/autoload_runtime.php(29): Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run() #8 /home/u196164738/domains/capucinemad.com/public_html/la-forge-des-enigmes/public/index.php(5): require_once('/home/u19616473...') #9 {main}
解决方案
1. 核心原因
Hostinger服务器处于公网环境,而ESP8266在本地WiFi内网中,公网服务器无法直接访问内网IP(如192.168.1.43)。本地WAMP能正常运行是因为你的电脑和ESP8266处于同一局域网,请求在内网内部完成。
2. 可行解决方法
方法一:内网穿透
给ESP8266配置内网穿透工具,生成公网可访问的域名或端口,Symfony代码中改用该公网地址发起请求。常用工具包括Ngrok、Frp,或路由器自带的端口映射功能(需路由器支持且公网IP为静态)。
方法二:前端发起请求
将请求逻辑从Symfony后端转移到前端浏览器,因为浏览器和ESP8266在同一WiFi内网,可直接调用ESP8266的内网IP:
document.getElementById('activate-btn').addEventListener('click', async () => { try { const response = await fetch('http://192.168.1.43/activeBottle'); if (response.ok) { alert('瓶子已激活'); window.location.reload(); } else { alert('连接瓶子失败'); } } catch (e) { alert('连接瓶子出错:' + e.message); } });
注意:若Symfony站点为HTTPS,浏览器会阻止HTTP混合内容,需给ESP8266配置HTTPS,或为站点添加混合内容豁免。
方法三:修正协议错误
代码中用https://拼接ESP8266的IP,但ESP8266仅监听80端口(HTTP),这会导致请求失败。修改协议为http://:
$response = $client->request('GET', "http://" . $wineGame->getIpBottle() . "/activeBottle", [ 'timeout' => 30.0 ]);
此修改仅解决协议问题,需配合内网穿透或前端请求方案才能彻底解决公网访问内网的核心问题。
3. 额外排查点
- 联系Hostinger客服确认服务器是否禁止出站请求到内网IP段;
- 检查ESP8266的防火墙设置,确保80端口允许外部访问(同一内网已正常,此可能性较低)。
内容的提问来源于stack exchange,提问作者Caps
相关产品推荐
相关产品推荐

