Express CORS не работает с socket.io - PullRequest
0 голосов
/ 22 апреля 2020

Я использовал cors для своего express сервера, но я не могу понять, почему он не работает. Может кто-нибудь помочь мне с этой проблемой?

Доступ к XMLHttpRequest по адресу https://tic-tac-toe-server.now.sh/socket.io/?EIO=3&transport=polling&t=N6Z2b4X 'origin' http://localhost: 8080 'был заблокирован политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Клиент:

import io from 'socket.io-client';
const socket = io('https://tic-tac-toe-server.now.sh')

Вот мой индекс. js

const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const cors = require('cors');


const router = require('./router');
const { addUser, removeUser, getUsers } = require('./users');
const { getMatch, addPlayer, destroyMatch } = require('./players');

const PORT = process.env.PORT || 5000;

const app = express();
const server = http.createServer(app);


const io = socketio(server);

app.use(router);
app.use(cors());


io.on('connection', function (socket) {
    const id = socket.id;
    let user_room = '';

    /**
     * User Joins to the global room
     */
    socket.on('join', function ({ name, room, playing = false }) {
        addUser({ id, name, room, playing }); // add user to users array
        user_room = room;
        socket.join(user_room);
        socket.join(id);
        socket.emit('user_joined', getUsers());
        socket.broadcast.emit('user_joined', getUsers()); // emit event with modified users array
    });

    /**
     * Match Started
     */

    socket.on('player_joined', user => {
        const match = getMatch();
        addPlayer(user.match, user);
        if(match.hasOwnProperty(user.match) && match[user.match].length === 2){
            socket.emit('player_joined', match[user.match]);
            socket.broadcast.to(user.match).emit('player_joined', match[user.match]);
        }
    });

    socket.on('move', (data) => {
        socket.emit('move', data);
        socket.broadcast.to(data.match).emit('move', data);
    });

    socket.on('emote', (data) => {
        socket.emit('emote_from', data);
        socket.broadcast.to(data.match).emit('emote_to', data);
    });


    /**
     * On user challenge
     */


    socket.on('challenge', (socketId) => {
        io.to(socketId).emit('accept', id);
    });

    socket.on('rejected', (socketId) => {
        io.to(socketId).emit('rejected', id);
    });

    socket.on('accepted', data => {
        io.to(data.opponent.id).emit('accepted', data);
        socket.emit('accepted', data);
    });

    socket.on('player_left_match', match => {
        socket.broadcast.to(match).emit('player_left_match');
    });

    socket.on('destroy_match', match => {
        destroyMatch(match);
    });

    /**
     * User Disconnect function
     */
    socket.on('disconnect', () => {
        socket.leave(user_room);
        socket.leave(id);
        removeUser(id); // remove user form users array
        socket.emit('user_left', getUsers());
        socket.broadcast.emit('user_left', getUsers());  // emit event with modified users
    })


});

server.listen(PORT, () => console.log(`Server running on port ${PORT}`));

1 Ответ

3 голосов
/ 22 апреля 2020

Вы можете указать socket.io использовать только транспорт webSocket, на который не распространяется CORS, изменив это:

const socket = io('https://tic-tac-toe-server.now.sh')

на следующее:

const socket = io('https://tic-tac-toe-server.now.sh', {transports: ['websocket']});

Некоторый фон. В конфигурации по умолчанию socket.io запускает каждое соединение с несколькими простыми http-запросами. Эти простые запросы HTTP требуют поддержки CORS на стороне сервера, если соединение является кросс-исходным. Но socket.io может быть настроен на go прямо на транспорт webSocket (что в конечном итоге и будет использоваться в любом случае), и соединения webSocket не подлежат ограничениям CORS.

Дизайн socket.io для Начать с http-опроса было в основном потому, что в первые дни поддержки webSocket его поддерживали не все браузеры, а не все серверные инфраструктуры. Но в настоящее время он довольно широко поддерживается.

Таким образом, указание socket.io начинать с транспорта webSocket с самого начала позволяет избежать многих потенциальных проблем с CORS.


Мы сейчас ищут другую проблему, и ошибка, отображаемая в консоли на https://tic-tac-toe-vue.now.sh/, исходит из этого кода в webSocket. js.

  try {
    this.ws =
      this.usingBrowserWebSocket && !this.isReactNative
        ? protocols
          ? new WebSocketImpl(uri, protocols)
          : new WebSocketImpl(uri)
        : new WebSocketImpl(uri, protocols, opts);
  } catch (err) {
    return this.emit('error', err);
  }

Похоже, что-то связано с React поскольку есть ссылка на isReactNative, но поскольку ваш код упакован и свернут, отладка здесь не очень проста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...