如何在使用Express后端的情况下,通过代理使socket.io在React和Vite中正常工作?

huangapple go评论71阅读模式
英文:

How can I make socket.io work through proxy with react and vite using express backend?

问题

I'm unable to get socket.io to work through proxy with react+vite (PORT 5173), express (PORT 5002).
我无法通过代理在react+vite(端口5173)和express(端口5002)中使socket.io工作。

I'm receiving an ERROR: server error from my current configuration. And my backend isn't receiving any connection attempts.
我从当前配置中收到“ERROR: server error”的错误消息。而且我的后端没有收到任何连接尝试。

I want the proxy to make the socket connection using my backend. (I think I'm trying to proxy the namespace e.g. const socket = io("/api"), to change from /api to http://localhost:5002))
我希望代理使用我的后端建立socket连接。(我认为我正在尝试代理命名空间,例如 const socket = io("/api"),将其从/api更改为http://localhost:5002))

Here are the relevant bits from my setup.
以下是我设置的相关部分。
My react / client component:
我的React / 客户端组件:

import { io } from 'socket.io-client';

export const socket = io('/ws', {
  autoConnect: false,
  withCredentials: true,
});

My vite.config.ts code:
我的vite.config.ts代码:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/ws': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: path => path.replace(/^\/ws/, ''),
      },
    }
  },
  plugins: [react()],
});

My express server side code:
我的express服务器端代码:

import express from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';

const app = express();
const httpServer = createServer(app);

app.use(
  cors({
    credentials: true,
    origin: process.env.CLIENT_URL,
  })
);

const port = 5002;

const io = new Server(httpServer, {
   cors: {
     origin: process.env.CLIENT_URL,
     credentials: true,
   },
});

io.on('connection', async (socket) => {...})

httpServer.listen(port, () => {
  console.log(`Server is listening on Port: ${port}`);
});

Whenever I change the path in the vite config and react component from '/ws' to '/socket', the error changes and I get an Error: xhr poll error. When this happens my backend receives a GET /.io/?EIO=4&transport=polling&t=OXLHE7k 404 1.653 ms - 5.
每当我将vite配置和react组件中的路径从'/ws'更改为'/socket'时,错误会更改并且我会收到Error: xhr poll error。当发生这种情况时,我的后端收到GET /.io/?EIO=4&transport=polling&t=OXLHE7k 404 1.653 ms - 5

When I remove the proxy from vite and just use the complete URL in the react component it works fine and everything functions as expected with no errors.
当我从vite中删除代理并在react组件中只使用完整的URL时,一切都正常运行,没有错误。

export const socket = io('http://localhost:5002', {
  autoConnect: false,
  withCredentials: true,
});

However I want to use the proxy now in dev, that's my goal and eventually I will use an nginx proxy in production.
但是我现在想在开发中使用代理,这是我的目标,最终我将在生产中使用nginx代理。

英文:

I'm unable to get socket.io to work through proxy with react+vite (PORT 5173), express (PORT 5002).
I'm receiving an ERROR: server error from my current configuration. And my backend isn't receiving any connection attempts.

I want the proxy to make the socket connection using my backend. (I think I'm trying to proxy the namespace e.g. const socket = io("/api"), to change from /api to http://localhost:5002))

Here are the relevant bits from my setup.
My react / client component:

import { io } from 'socket.io-client';

export const socket = io('/ws', {
  autoConnect: false,
  withCredentials: true,
});

My vite.config.ts code:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/ws': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: path => path.replace(/^\/ws/, ''),
      },
    }
  },
  plugins: [react()],
});

My express server side code:

import express, from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';

const app = express();
const httpServer = createServer(app);

app.use(
  cors({
    credentials: true,
    origin: process.env.CLIENT_URL,
  })
);

const port = 5002;

const io = new Server(httpServer, {
   cors: {
     origin: process.env.CLIENT_URL,
     credentials: true,
   },
});

io.on('connection', async (socket) => {...})

httpServer.listen(port, () => {
  console.log(`Server is listening on Port: ${port}`);
});

Whenever I change the path in the vite config and react component from 'ws' to 'socket', the error changes and I get an Error: xhr poll error. When this happens my backend receives a GET /.io/?EIO=4&transport=polling&t=OXLHE7k 404 1.653 ms - 5

When I remove the proxy from vite and just use the complete url in the react component it works fine and everything functions as expected with no errors,

export const socket = io('http://localhost:5002', {
  autoConnect: false,
  withCredentials: true,
});

However I want to use the proxy now in dev, that's my goal and eventually I will use an nginx proxy in production.

答案1

得分: 1

以下是翻译好的部分:

解决方案是只需使用 const socket = io(options)。
https://socket.io/docs/v4/client-initialization/#from-the-same-domain

然后 vite 配置应为:

export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/socket.io/': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
      },
    }
  },
  plugins: [react()],
});
英文:

The solution was to just use const socket = io(options)
https://socket.io/docs/v4/client-initialization/#from-the-same-domain

Then the vite config would be:

export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/socket.io/': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
      },
    }
  },
  plugins: [react()],
});

huangapple
  • 本文由 发表于 2023年5月26日 07:43:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76336844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定