在通过Nginx反向代理连接到使用Socket.IO的服务器时发生XHR轮询错误

移动开发 2026-07-09

我的socket.io服务器在不使用nginx代理时运行正常,但当我使用nginx代理时,在尝试连接时会得到一个 xhr poll error

这是我的nginx的 server块,看起来像这样:

location /example/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:3336/;
    proxy_set_header Host $host;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_cache_bypass $http_upgrade;
}

这是位于我的express.js API根目录下的代码:

// index.ts
const server = http.createServer(app);
connectIo(server)

// socket library
export const connectIo = (server: http.Server) => {
    socketIo = new Server(server)

    socketIo.on('connection', (socket) => {
        // Join with condition
    })
}

在我的客户端 react-native 端,下面是我连接该socket的代码:

socket = io(`http://172.21.48.1/example`, {
    query: { unique_code: String(userId) },
});

socket.on("connect_error", (err) => {
     console.log("connect_error:", err.message); // xhr poll error
});

那个172.21.48.1是我的局域网IP地址,该主机的IP并没有问题,因为它可以接受普通的API调用,直接走到nginx,并按你在nginx配置中所看到的把请求代理转发给 http://localhost:3336/,但如果像下面这样直接连接API而不经过nginx

socket = io(`http://192.168.100.9:3336`, {
    query: { unique_code: String(userId) },
});

这在不经nginx的情况下能正常工作,那我该如何让它在经过nginx代理后也能正常工作?

解决方案

客户端和服务器之间存在命名空间/路径不匹配,自定义路径必须在服务端和客户端都保持一致。

服务器有默认路径 socket.io(这也是它在没有代理时能正常工作的原因),但客户端在使用代理时,服务器URL中带有 example,会把它解析为 example 命名空间,导致xhr poll错误。

所以你需要把 /example 放在 path 选项里,而不是放在服务器URL里,但因为Nginx会将它去除,所以它不会匹配服务器的默认路径,因此你还需要再加上 socket.io,以便完全匹配服务器的命名空间。

请尝试以下配置:

socket = io(`http://172.21.48.1`, {
    query: { unique_code: String(userId) },
    path: '/example/socket.io'
});

参见:server-options/#path

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章