无法连接到Heroku上的Socket.IO服务器

时间:2020-11-05 18:59:19

标签: node.js typescript heroku socket.io

我想在Vercel上托管我的前端(我正在使用Nextjs),并且由于它的API路由不支持套接字连接,所以我决定将应用程序的这一部分移至Heroku。我的问题是,当我在开发环境中从前端使用服务器时,它工作正常,但是将其部署到Heroku时,出现此错误:

Access to XMLHttpRequest at 'https://my-socket-server.herokuapp.com/socket.io/?EIO=3&transport=polling&t=NMPkkyL' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我的服务器代码如下:

import express from 'express';
import io, { Namespace } from 'socket.io';
import { PORT, menus, socketServerConfig, adminRoom } from './util/config';

const server = express().listen(PORT, () =>
  console.log(`server running on port ${PORT}`)
);
const socketServer = io(server, socketServerConfig);

const attachSocketHandlers = (server: Namespace) => {
  server.on('connection', socket => {
    const handlers = {
      'admin-log-in': () => {
        socket.join(adminRoom);
      },
      'need-waiter': (table: Table) => {
        server.to(adminRoom).emit('need-waiter', table);
      },
      'need-receipt': (table: Table) => {
        server.to(adminRoom).emit('need-receipt', table);
      },
      order: (order: Order) => {
        server.to(adminRoom).emit('order', order);
      },
      disconnect: () => {
        socket.leaveAll();
      },
    };

    Object.entries(handlers).map(([event, handler]) => {
      socket.on(event, handler);
    });
  });
};

menus.forEach(menu => {
  const namespacedServer = socketServer.of(`/${menu}`);
  attachSocketHandlers(namespacedServer);
});

我从socket.io文档中了解到,如果您在配置中未列出任何来源,则它允许所有来源访问套接字服务器。这是我的socketServerConfig:

import { ServerOptions } from 'socket.io';

const defaultPort = 4000;

export const PORT = process.env?.PORT ?? defaultPort;

export const menus = ['more'];

export const adminRoom = 'admin';

export const socketServerConfig: ServerOptions = {
  serveClient: false, // i don't serve any static files
};

这是我从前端连接的方式:

const url = 'https://my-socket-server.herokuapp.com/';
const io = connect(`${url}${menu}`);

我尝试了SOF的各种解决方案,但我无法使其正常工作,我们将不胜感激。预先感谢。

1 个答案:

答案 0 :(得分:0)

尝试执行npm install cors并将其添加到您的服务器:

const cors = require('cors');
const whitelist = [
  'http://localhost:3000',
  YOUR FRONTEND URL
];
const corsOptions = {
  origin: function (origin, callback) {
    console.log('** Origin of request ' + origin);
    if (whitelist.indexOf(origin) !== -1 || !origin) {
      console.log('Origin acceptable');
      callback(null, true);
    } else {
      console.log('Origin rejected');
      callback(new Error('Not allowed by CORS'));
    }
  },
};
express().use(cors(corsOptions));

希望这对您有所帮助!