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

React+Express+Socket.io使用Ngrok无法建立连接的问题求助

Socket.io通过Ngrok跨网连接失败问题

版本信息

客户端:socket.io-client@4.7.2
服务端:socket.io@4.7.2

服务端代码(server/server.js)

const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const socketioJwt = require('socketio-jwt');
const cors = require('cors');
const helmet = require('helmet');

const app = express();

// 启用全局CORS
app.use(cors());

// 启用代理信任
app.set("trust proxy", 1);

// 启用Helmet增强安全
app.use(helmet());

// 解析请求中的JSON数据
app.use(express.json());

const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: {
    origin: "http://localhost:3000", // 替换为Ngrok客户端HTTPS地址
    methods: ["GET", "POST"],
    credentials: true,
  },
});

const port = process.env.PORT || 4821;

io.use((socket, next) => {
  const clientIP = socket.handshake.address;

  // 配置JWT认证中间件
  io.use(
    socketioJwt.authorize({
      secret: secretKey, // 来自.env文件的密钥
      handshake: true,
    })
  );
});

客户端代码(client/src/App.js)

import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';
import './styles.css';

const jwt = require('jsonwebtoken');
const token = jwt.sign(
  {
    username: "myUsername",
  },
  process.env.REACT_APP_JWT_SECRET
);
const socket = io("http://localhost:4821", { // 替换为Ngrok服务端HTTPS地址
  query: { token },
});

socket.on('connect', () => {
  console.log('Connected to the server');
});

socket.on('error', (error) => {
  console.error('WebSocket Error:', error);
});

Ngrok配置步骤

服务端配置(Linux Ubuntu虚拟机/Node.js LTS 18)

  • 执行sudo ufw status确认防火墙已激活,执行sudo ufw allow 4821开放端口,再执行sudo ufw reload生效
  • 启动服务端:npm start(启动脚本为nodemon node server.js)
  • 启动Ngrok隧道:ngrok start server(ngrok.yml配置为http localhost:4821)
  • 复制Ngrok生成的HTTPS服务端地址
  • 将该地址替换到客户端代码的Socket.io连接地址中,重启客户端

客户端配置(MAC)

  • 启动客户端:npm start
  • 启动Ngrok隧道:ngrok start client(ngrok.yml配置为http localhost:3000)
  • 复制Ngrok生成的HTTPS客户端地址
  • 将该地址替换到服务端代码的CORS origin配置中,重启服务端

问题现象

  • 本地环境下,客户端localhost:3000与服务端localhost:4821的Socket.io连接完全正常
  • 通过Ngrok隧道访问时,无法建立Socket.io连接,且浏览器控制台无任何报错信息

浏览器网络面板详情

轮询请求(ALL标签)

Request URL: https://f65b-185-213-154-249.ngrok-free.app/socket.io/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNhdG9zaGlAMjFubWlsbC5pbyIsImlhdCI6MTY5ODUwNjE1M30.v5hCOKlmMHf3RSEdXTumzO7PEtKzYz-XZrA6CqPsCkg&EIO=4&transport=polling&t=OjssoEr 
Request Method: GET 
Status Code: 200 OK (from service worker) 
Referrer Policy: strict-origin-when-cross-origin 
Access-Control-Allow-Origin: * 
Content-Length: 1396 
Content-Security-Policy: default-src 'self' https://cdn.ngrok.com 'unsafe-eval' 'unsafe-inline'; img-src data: w3.org/svg/2000 
Content-Type: text/html 
Date: Sat, 28 Oct 2023 15:15:55 GMT 
Ngrok-Trace-Id: 7ca3e23723940ef090231cf42ad421a1 
Referrer-Policy: no-referrer 
X-Content-Type-Options: nosniff 
Accept: */* 
Referer: https://ed5e-185-213-154-249.ngrok-free.app/ 
Sec-Ch-Ua: "Chromium";v="118", "Brave";v="118", "Not=A?Brand";v="99" 
Sec-Ch-Ua-Mobile: ?0 
Sec-Ch-Ua-Platform: "macOS"

WebSocket请求(WS标签)

Request URL: wss://ed5e-185-213-154-249.ngrok-free.app/sockjs-node 
Request Method: GET 
Status Code: 101 Switching Protocols 
Connection: Upgrade 
Ngrok-Trace-Id: 58a6ffcdbd0cd5a1ef2d633378c24398 
Sec-Websocket-Accept: ONgwe/ms0WvXB6Tb2eIyPvx6dVo= 
Upgrade: websocket 
Accept-Encoding: gzip, deflate, br 
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 
Cache-Control: no-cache 
Connection: Upgrade 
Cookie: abuse_interstitial=ed5e-185-213-154-249.ngrok-free.app 
Host: ed5e-185-213-154-249.ngrok-free.app 
Origin: https://ed5e-185-213-154-249.ngrok-free.app 
Pragma: no-cache 
Sec-Gpc: 1 
Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits 
Sec-Websocket-Key: QQjVTB/9a2Ou5OcaPX2YnA== 
Sec-Websocket-Version: 13 
Upgrade: websocket 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36

问题猜测与待验证方案

  • 怀疑问题源于Ngrok未配置Let's Encrypt SSL证书
  • 不确定是否需要在客户端Socket.io配置中添加以下参数:
// client/src/App.js 修改后的Socket连接配置
const socket = io("https://ngrok-url.com", {
  query: { token },
  withCredentials: true, // 新增
  transports: ['websocket', 'polling'], // 新增(注意参数名应为transports而非transport)
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:07:32