Reputation: 33
I just recently started an online tutorial on how to make a multiplayer snake.io game with Node js and socket.io.
https://www.youtube.com/watch?v=ppcBIHv_ZPs
Things went pretty smooth setting things up for the client side, but once I tried to establish a socket,(15:20 in video), I get errors in the client side browser chrome console, trying to establish a communication. At first I received an error as follows
127.0.0.1/:1 Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=3&transport=polling&t=NfTLuxq' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I then did some research on what CORS is, and to my understanding it is like a security protocol which restricts connections between different URL's, with this error wanting a header for security reasons?
I saw a user say he made it so the socket.io library was the same for both client side and server side. So I deleted the socket.io files from my server side and reinstalled them with the same version I pulled into the client side with a cdn. I used the command , 'yarn add [email protected]'. I figured this would solve the problem however I then received a different error,
"Failed to load resource: net::ERR_CONNECTION_REFUSED"
I also don't understand why in this project we are pulling in socket.io from a cdn in index.html (which I'm not exactly sure how works), but then using yarn to add socket.io on the server side, and then we have to import it in again using 'require'. I'm not sure I understand the difference between these two methods of importing socket.io and why we are using two different methods.
Any help with clearing up some of my confusion on why I'm receiving these errors and the previous question would be greatly appreciated!
Code for index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>>MultiPlayer Snake</title>
<!-- Import bootstrap-css --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<!-- Create a section that is 100% height of window. -->
<div class="container h-100">
<section class="vh-100">
<div id="gameScreen" class="h-100">
<!-- Center canvas both horizontally and vertically using a few bootstrap classes -->
<div class="d-flex flex-column align-items-center justify-content-center h-100">
<canvas id="canvas"></canvas>
</div>
</div>
</div>
</section>
<!-- Pulling in socket.io from a cdn? -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<!-- Importing index.js -->
<script src="index.js"></script>
</body>
</html>
Code for index.js
const BG_COLOUR = '#231f20';
const SNAKE_COLOUR = '#c2c2c2';
const FOOD_COLOUR = '#e66916';
const socket = io('http://localhost:3000');
socket.on('init', handleInit);
// Get a hold of the game screen div from html
const gameScreen = document.getElementById('gameScreen');
// Create canvas and context elements, context->state
let canvas, ctx;
const gameState = {
player: {
pos: {
x: 3,
y: 10,
},
vel: {
x: 1,
y: 0,
},
snake: [
{x: 1, y: 10},
{x: 2, y: 10},
{x: 3, y: 10},
],
},
food: {
x: 7,
y: 7,
},
gridsize: 20,
};
// Initialize everything
function init()
{
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
canvas.width = canvas.height = 600;
ctx.fillStyle = BG_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
document.addEventListener('keydown', keydown);
}
function keydown(e)
{
console.log(e.keycode);
}
init();
function paintGame(state)
{
ctx.fillStyle = BG_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
const food = state.food;
const gridsize = state.gridsize;
const size = canvas.width / gridsize;
ctx.fillStyle = FOOD_COLOUR;
ctx.fillRect(food.x * size, food.y * size, size, size);
paintPlayer(state.player, size, SNAKE_COLOUR);
}
function paintPlayer(playerState, size, COLOUR)
{
const snake = playerState.snake;
ctx.fillStyle = COLOUR;
for (let cell of snake)
{
ctx.fillRect(cell.x * size, cell.y * size ,size, size);
}
}
paintGame(gameState);
function handleInit(msg)
{
console.log(msg);
}
Code for server.js
// Import socket.io
const io = require('socket.io')();
// add listener
io.on('connection', client => {
// Callback function
// Raise an event.
client.emit('init', {data: 'hello world' });
});
io.listen(3000);
My file structure. My file sctructure
After feedback from this question I added code to handle cos and again I received an error message , this time
Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=3&transport=polling&t=NfUVBF5' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:8080' that is not equal to the supplied origin.
I wrote this code in server.js
const io = require("socket.io")( {
cors: {
origin: "http://localhost:8080",
methods: ["GET", "POST"]
}
});
Upvotes: 1
Views: 1706
Reputation: 28
Cross Origin Resource Sharing is used so that a website cannot access resources of another website until it is allowed through server to by adding headers
Access-Control-Allow-Origin: <Site Name> or Wild Card (*)
As I think either you are directly opening HTML file or accessing it by another server so domains are going to differ, For ex. HTML File is opening at port http://localhost:8888 and WebSocket Server is running at port 3000 so that's why you are facing CORS.
Solutions:
const io = require("socket.io")(httpServer, {
cors: {
origin: "*",
methods: ["GET", "POST"],
credentials:true
}
});
Allow-Control-Allow-Origin
const httpServer = require("http").createServer();
const io = require("socket.io")(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
More Resources To Refer:
Upvotes: 1