I want to deploy my node.js on vps. my project tech stack is node.js , express , peer.js and socket.io I deployed the project on server but cors blocked error occurs
Picture of the error is
I am using ejs as template engine. Cors block my origin I used * but the error is same
code of app.js
const express = require("express");
const app = express();
const cors = require("cors");
const http = require("http");
const server = http.createServer(app);
const io = require("socket.io")(server, {
cors: {
origin: "https://meet.fiyxer.com:*",
methods: ["GET", "POST"],
allowedHeaders: ["Content-Type"],
credentials: true,
},
});
app.use(
cors({
origin: "https://meet.fiyxer.com",
credentials: true,
})
)
const { ExpressPeerServer } = require("peer");
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static("public"));
app.set("views", "./views");
app.set("view engine", "ejs");
app.use("/peerjs", ExpressPeerServer(server, { debug: true }));
let rooms = {}; // Store room data including the host
app.get("/", (req, res) => {
res.render("index.ejs");
});
app.post("/join", (req, res) => {
const meetingCode = req.body.code;
console.log("meetingCode", meetingCode);
res.redirect(`/${meetingCode}`);
});
app.post("/create", (req, res) => {
function generateRandomSegment(length) {
const characters = "abcdefghijklmnopqrstuvwxyz";
let result = "";
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
// Function to generate the formatted string
function generateRandomString() {
const segment1 = generateRandomSegment(3); // Generate first segment
const segment2 = generateRandomSegment(3); // Generate second segment
const segment3 = generateRandomSegment(4); // Generate third segment
return `${segment1}-${segment2}-${segment3}`;
}
const randomString = generateRandomString();
res.redirect(`/${randomString}`);
});
app.get("/:room", (req, res) => {
res.render("room.ejs", { roomId: req.params.room });
});
io.on("connection", (socket) => {
socket.on("join-room", (roomId, userId, userName) => {
socket.join(roomId);
if (!rooms[roomId]) {
rooms[roomId] = { host: userId }; // Initialize host for new room
}
socket.emit("host-info", rooms[roomId].host); // Send host info to the client
// Broadcast to others in the room that a new user has connected
socket.to(roomId).broadcast.emit("user-connected", userId);
socket.on("message", (message) => {
io.to(roomId).emit("createMessage", message, userName);
});
socket.on("disconnect", () => {
socket.to(roomId).broadcast.emit("user-disconnected", userId, userName);
if (rooms[roomId] && rooms[roomId].host === userId) {
io.to(roomId).emit("meeting-ended");
delete rooms[roomId];
}
});
socket.on("end-meeting", () => {
// Only allow the host to end the meeting
if (rooms[roomId] && rooms[roomId].host === userId) {
io.to(roomId).emit("meeting-ended");
delete rooms[roomId];
}
});
});
});
server.listen(process.env.PORT || 3030, () => {
console.log("Server is running on port: " + (process.env.PORT || 3030));
});
script.js code is
const socket = io("https://meet.fiyxer.com", {
withCredentials: true,
extraHeaders: {
"Access-Control-Allow-Origin": "https://meet.fiyxer.com",
},
});
const videoGrid = document.getElementById("video-grid");
const myVideo = document.createElement("video");
myVideo.muted = true;
const showChat = document.querySelector("#showChat");
const backBtn = document.querySelector(".header__back");
const muteButton = document.querySelector("#muteButton");
const stopVideo = document.querySelector("#stopVideo");
const shareScreenButton = document.querySelector("#shareScreen");
const inviteButton = document.querySelector("#inviteButton");
const endMeetingButton = document.querySelector("#endMeetingButton");
backBtn.addEventListener("click", () => {
document.querySelector(".main__left").style.display = "flex";
document.querySelector(".main__left").style.flex = "1";
document.querySelector(".main__right").style.display = "none";
document.querySelector(".header__back").style.display = "none";
});
showChat.addEventListener("click", () => {
document.querySelector(".main__right").style.display = "flex";
document.querySelector(".main__right").style.flex = "1";
document.querySelector(".main__left").style.display = "none";
document.querySelector(".header__back").style.display = "block";
});
// Check if username is already in local storage
let user = localStorage.getItem("username");
if (!user) {
user = prompt("Enter your name");
localStorage.setItem("username", user); // Save username in local storage
}
var peer = new Peer({
host: '127.0.0.1',
port: 3030,
path: '/peerjs',
config: {
'iceServers': [
{ url: 'stun:stun01.sipphone.com' },
{ url: 'stun:stun.ekiga.net' },
{ url: 'stun:stunserver.org' },
{ url: 'stun:stun.softjoys.com' },
{ url: 'stun:stun.voiparound.com' },
{ url: 'stun:stun.voipbuster.com' },
{ url: 'stun:stun.voipstunt.com' },
{ url: 'stun:stun.voxgratia.org' },
{ url: 'stun:stun.xten.com' },
{
url: 'turn:192.158.29.39:3478?transport=udp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
},
{
url: 'turn:192.158.29.39:3478?transport=tcp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
},
]
},
debug: 3
});
let myVideoStream;
let currentStream;
let screenSharing = false;
let screenVideo = document.createElement("video");
let peers = {}; // Store peer connections
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true
})
.then((stream) => {
myVideoStream = stream;
currentStream = stream;
addVideoStream(myVideo, stream);
peer.on("call", (call) => {
call.answer(currentStream); // Answer with the current stream (either webcam or screen share)
const video = document.createElement("video");
call.on("stream", (userVideoStream) => {
addVideoStream(video, userVideoStream);
});
call.on("close", () => {
video.remove();
});
peers[call.peer] = call;
});
socket.on("user-connected", (userId) => {
setTimeout(() => {
connectToNewUser(userId, currentStream);
}, 1000); // Give the peer time to set up
});
socket.on("user-disconnected", (userId, user) => {
if (peers[userId]) peers[userId].close();
removeVideo(userId);
Swal.fire({
text: `${user} has left the meeting`,
timer: 5000,
showConfirmButton: false,
});
});
socket.on("meeting-ended", () => {
Swal.fire({
icon: 'warning',
title: 'Meeting Ended',
text: 'The host has ended the meeting.',
confirmButtonText: 'OK'
}).then(() => {
window.location.href = '/';
});
});
})
.catch((error) => {
console.error("Error accessing media devices:", error);
});
const connectToNewUser = (userId, stream) => {
const call = peer.call(userId, stream);
const video = document.createElement("video");
call.on("stream", (userVideoStream) => {
addVideoStream(video, userVideoStream);
});
call.on("close", () => {
video.remove();
});
peers[userId] = call;
};
peer.on("open", (id) => {
socket.emit("join-room", ROOM_ID, id, user);
});
const addVideoStream = (video, stream) => {
video.srcObject = stream;
video.addEventListener("loadedmetadata", () => {
video.play();
});
videoGrid.append(video); // Ensure the video is appended to the grid
video.id = stream.id; // Assign the stream ID to the video element
};
const removeVideo = (userId) => {
const video = document.getElementById(userId);
if (video) {
video.remove();
}
};
let text = document.getElementById("chat_message");
let send = document.getElementById("send");
let messages = document.querySelector(".messages");
send.addEventListener("click", () => {
if (text.value.length !== 0) {
socket.emit("message", text.value);
text.value = "";
}
});
text.addEventListener("keydown", (e) => {
if (e.key === "Enter" && text.value.length !== 0) {
socket.emit("message", text.value);
text.value = "";
}
});
muteButton.addEventListener("click", () => {
const enabled = myVideoStream.getAudioTracks()[0].enabled;
myVideoStream.getAudioTracks()[0].enabled = !enabled;
muteButton.innerHTML = enabled ? `<i class="fas fa-microphone-slash"></i>` : `<i class="fas fa-microphone"></i>`;
muteButton.classList.toggle("background__red");
});
stopVideo.addEventListener("click", () => {
const enabled = myVideoStream.getVideoTracks()[0].enabled;
myVideoStream.getVideoTracks()[0].enabled = !enabled;
stopVideo.innerHTML = enabled ? `<i class="fas fa-video-slash"></i>` : `<i class="fas fa-video"></i>`;
stopVideo.classList.toggle("background__red");
});
inviteButton.addEventListener("click", () => {
// Copy URL to clipboard
const urlToCopy = window.location.href;
navigator.clipboard.writeText(urlToCopy)
.then(() => {
// Show SweetAlert confirmation
Swal.fire({
icon: 'success',
title: 'URL Copied!',
text: 'Link copied to clipboard. You can now share it.',
timer: 3000, // Automatically close after 3 seconds
showConfirmButton: false
});
})
.catch((error) => {
console.error('Error copying text: ', error);
// Show SweetAlert for error (optional)
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Failed to copy link. Please try again.'
});
});
});
endMeetingButton.addEventListener("click", () => {
Swal.fire({
title: 'End Meeting',
text: "Are you sure you want to leave the meeting?",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#480da1',
cancelButtonColor: '#1a1a1a',
confirmButtonText: 'Yes, end it!'
}).then((result) => {
if (result.isConfirmed) {
// Remove username from local storage
localStorage.removeItem("username");
socket.emit("end-meeting");
window.location.href = '/';
}
});
});
socket.on("createMessage", (message, userName, userId) => {
messages.innerHTML += `
<div class="message">
<b><i class="far fa-user-circle"></i> <span>${userName === user ? "me" : userName}</span></b>
<span>${message}</span>
</div>`;
});
// End meeting and remove username on tab close
window.addEventListener("beforeunload", (event) => {
// Remove username from local storage
localStorage.removeItem("username");
// Emit end-meeting event to server
socket.emit("end-meeting");
// Optional: Display confirmation message
event.preventDefault();
event.returnValue = "";
});
The CORS (Cross-Origin Resource Sharing) error you’re encountering typically occurs when your frontend JavaScript code, running on a different origin (domain, protocol, or port) than your backend server, attempts to make requests that violate the Same-Origin Policy. Here’s how you can resolve this issue:
1. Server-Side Configuration
Ensure your server allows CORS requests. In your Express server setup (app.js
), you’ve already configured CORS middleware using cors
. Here’s a revised version to properly configure CORS for both Express and Socket.io:
const express = require("express");
const app = express();
const cors = require("cors");
const http = require("http");
const server = http.createServer(app);
const { v4: uuidv4 } = require("uuid");
const io = require("socket.io")(server, {
cors: {
origin: "http://meet.fiyxer.com:*",
methods: ["GET", "POST"],
allowedHeaders: ["Content-Type"],
credentials: true,
},
});
const { ExpressPeerServer } = require("peer");
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static("public"));
app.set("views", "./views");
app.set("view engine", "ejs");
app.use("/peerjs", ExpressPeerServer(server, { debug: true }));
let rooms = {}; // Store room data including the host
app.get("/", (req, res) => {
res.render("index.ejs");
});
app.post("/join", (req, res) => {
const meetingCode = req.body.code;
console.log("meetingCode", meetingCode);
res.redirect(`/${meetingCode}`);
});
app.post("/create", (req, res) => {
function generateRandomSegment(length) {
const characters = "abcdefghijklmnopqrstuvwxyz";
let result = "";
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
// Function to generate the formatted string
function generateRandomString() {
const segment1 = generateRandomSegment(3); // Generate first segment
const segment2 = generateRandomSegment(3); // Generate second segment
const segment3 = generateRandomSegment(4); // Generate third segment
return `${segment1}-${segment2}-${segment3}`;
}
const randomString = generateRandomString();
res.redirect(`/${randomString}`);
});
app.get("/:room", (req, res) => {
res.render("room.ejs", { roomId: req.params.room });
});
io.on("connection", (socket) => {
socket.on("join-room", (roomId, userId, userName) => {
socket.join(roomId);
if (!rooms[roomId]) {
rooms[roomId] = { host: userId }; // Initialize host for new room
}
socket.emit("host-info", rooms[roomId].host); // Send host info to the client
// Broadcast to others in the room that a new user has connected
socket.to(roomId).broadcast.emit("user-connected", userId);
socket.on("message", (message) => {
io.to(roomId).emit("createMessage", message, userName);
});
socket.on("disconnect", () => {
socket.to(roomId).broadcast.emit("user-disconnected", userId, userName);
if (rooms[roomId] && rooms[roomId].host === userId) {
io.to(roomId).emit("meeting-ended");
delete rooms[roomId];
}
});
socket.on("end-meeting", () => {
// Only allow the host to end the meeting
if (rooms[roomId] && rooms[roomId].host === userId) {
io.to(roomId).emit("meeting-ended");
delete rooms[roomId];
}
});
});
});
server.listen(process.env.PORT || 3030, () => {
console.log("Server is running on port: " + (process.env.PORT || 3030));
});
2. Client-Side Configuration
In your client-side JavaScript (script.js
), ensure that your Socket.io client connection uses the correct URL:
const socket = io("http://meet.fiyxer.com", {
withCredentials: true,
extraHeaders: {
"Access-Control-Allow-Origin": "http://meet.fiyxer.com",
},
});
3. Verify CORS Settings
- Origin: Ensure that
http://meet.fiyxer.com
matches the origin you are using in your client-side code. - Credentials: Set
withCredentials: true
in your Socket.io client to allow cookies to be sent in cross-origin requests.
4. Restart and Test
After making these changes:
- Restart your Node.js server.
- Clear your browser cache or use Incognito mode to test.
These steps should help resolve the CORS issue and allow your Socket.io connection to function properly across different origins. If you encounter further issues, check your server logs for any additional error messages related to CORS or network connectivity.