socket.io Connection Problem node.js Hosted on Domain - node.js

I have tried a million different ways to connect via socket.io.
I keep getting the following error:
WebSocket connection to 'wss:/example.com/socket.io/?EIO=3&transport=websocket&sid=CiLGqnUNiDKvOsreAAAW' failed:
server.js
const { v4: uuidV4 } = require('uuid')
const express = require('express')
const app = express()
const PORT = process.env.PORT || 443;
const fs = require('fs')
const https = require('https')
const options = {
key:fs.readFileSync('server-key.pem', 'utf8').toString(),
cert: fs.readFileSync('server-cert.pem', 'utf8').toString()
}
const httpsServer = https.createServer(options, app)
const io = require('socket.io')(httpsServer)
app.set('view engine', 'ejs')
app.use(express.static('public'))
app.get('/', (req, res) => {
res.redirect(`/${uuidV4()}`)
})
app.get('/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
io.on('connection', socket => {
socket.on('join-room', (roomId, userId) => {
socket.join(roomId)
socket.to(roomId).broadcast.emit('user-connected', userId)
socket.on('disconnect', () => {
socket.to(roomId).broadcast.emit('user-disconnected', userId)
})
})
})
httpsServer.listen(PORT, () => console.log(`Server is running on PORT ${PORT}`));
scripts.js
const socket = io.connect('https://example.com:443')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, {})
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
addVideoStream(myVideo, stream)
myPeer.on('call', call => {
call.answer(stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
})
socket.on('user-connected', userId => {
connectToNewUser(userId, stream)
})
})
socket.on('user-disconnected', userId => {
if (peers[userId]) peers[userId].close()
})
myPeer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
function connectToNewUser(userId, stream) {
const call = myPeer.call(userId, stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
call.on('close', () => {
video.remove()
})
peers[userId] = call
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
room.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script>
const ROOM_ID = "<%= roomId %>"
</script>
<script defer src="https://unpkg.com/peerjs#1.2.0/dist/peerjs.min.js"></script>
<script src="/socket.io/socket.io.js" defer></script>
<script src="script.js" defer></script>
<title>Document</title>
<style>
#video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 300px;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="video-grid"></div>
</body>
</html>
How can I connect via socket.io? I'm working with my own domain and using cpanel and running node.js.
I am trying to follow the tutorial at: https://github.com/WebDevSimplified/Zoom-Clone-With-WebRTC

Related

Not able to deploy node js app on heroku properly

I had made a video-call app which is running well on my local pc, but when I pushed all files to heroku, I am not able to see other person's video.
Here is my script.js(front-end client side file):
//declaring socket constant
const socket = io("/");
//identifying video grid element
const videoGridElement = document.getElementById("video-grid");
//creating new element
const myVideo = document.createElement("video");
myVideo.muted = true;
//peerjs variable declaring here
const peer = new Peer(undefined, {
host:host,
port:port,
path: '/a'
})
//getting media of user
var getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
peer.on("open", function(id){
socket.emit("join-room", ROOM_ID, id);
});
let myVideoStream;
navigator.mediaDevices.getUserMedia({
video:true,
audio:true
}).then(function(stream){
myVideoStream = stream;
addVideoStream(myVideo, stream)
peer.on("call", function(call){
call.answer(stream);
const video = document.createElement("video");
call.on("stream", function(userVideoStream){
addVideoStream(video, userVideoStream);
})
});
socket.on("user-connected", function(userId){
connectToNewUser(userId, stream);
});
})
peer.on("call", function(call){
getUserMedia({
video:true,
audio:true
}, function(stream){
call.answer(stream);
const video = document.createElement("video");
call.on("stream", function (remoteStream) {
addVideoStream(video, remoteStream);
});
}, function(err){
console.log(err);
})
})
const addVideoStream = function(videoElement, stream){
videoElement.srcObject = stream;
videoElement.addEventListener("loadedmetadata", () => {
videoElement.play();
});
videoGridElement.append(videoElement);
let totalUsers = document.getElementsByTagName("video").length;
if (totalUsers > 1) {
for (let index = 0; index < totalUsers; index++) {
document.getElementsByTagName("video")[index].style.width =
100 / totalUsers + "%";
}
}
}
const connectToNewUser = function(userId, stream){
var call = peer.call(userId, stream)
var video = document.createElement("video");
call.on("stream", function(userVideoStream){
addVideoStream(video, userVideoStream);
})
}
Here is the server.js file(server side file):
require("dotenv").config();
const express = require("express");
const app = express();
//making server constant
const server = require("http").Server(app);
//requirinng uuid package
const { v4 : uuidv4 } = require("uuid");
//declaring io constant
const io = require("socket.io")(server);
//using peer server
const {ExpressPeerServer} = require("peer");
const peerServer = ExpressPeerServer(server, {
debug: true
})
//setting view engine to ejs and express to use static files
app.set("view engine", "ejs");
app.use(express.static("public"));
//
app.use("/a", peerServer);
//when user gets on the home route, it redirects him to new room
app.get("/", function(req, res){
const id = uuidv4();
res.redirect("/"+ id);
})
//listening on port 3030
const port = process.env.PORT || 3030;
server.listen(port);
//using routing parametes of express, to pass different room files to
//different rooms
app.get("/:room", function(req,res){
console.log(req.hostname);
res.render("room", {roomId:req.params.room, myPort:port, myHost: req.hostname});
})
//on connection of any new user
io.on("connection", function(socket){
//when joinroom is emmited from frontend along with roomid and,
//userId, this code inside it will be executed
socket.on("join-room", function(roomId, userId){
socket.join(roomId);
socket.to(roomId).emit("user-connected", userId);
})
})
And here is the room.ejs file in the room directory:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Room</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/style.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/peerjs/1.3.1/peerjs.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
const ROOM_ID = "<%= roomId %>";
const port = "<%= myPort %>";
const host = "<%= myHost %>";
</script>
</head>
<body>
<h1>Hi there!</h1>
<div class="main">
<div class="main__left">
<div class="main__videos">
<div id="video-grid">
</div>
</div>
</div>
</div>
<script src="/script.js">
</script>
</body>
</html>
Package.json file:
{
"name": "zoom-clone",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.6",
"express": "^4.17.1",
"peer": "^0.5.3",
"socket.io": "^2.4.1",
"uuid": "^8.3.2"
}
}
I am not able to determine whether I have made correct changes required for deploying or not. Please help me identify if I am missing some code piece here.
Thanks!

call.on("stream") of peerjs is triggering in debug mode but not in non-debug mode

I am new to use Peerjs. While I am using my customer Peerjs server (w/ or w/o ssl) the on stream event is not triggering in non-debug mode. But when I put a debugger in dev mode in browser to see the problem, no problem observed and the event triggered.
Please find the code snippet below for your reference and kindly help me on the same.
app.js
const express = require('express');
const app = express();
const fs = require("fs");
const https = require("https");
const opts = {
key: fs.readFileSync('./certificates/key.pem', 'utf-8'),
cert : fs.readFileSync('./certificates/cert.pem', 'utf-8'),
}
const httpsServer = https.createServer(opts, app);
const io = require("socket.io")(httpsServer);
app.set("view engine", "ejs");
app.use(express.static("public"));
app.get("/" , (req,res)=>{
res.redirect("1")
});
app.get("/:room" , (req,res)=>{
res.render("index", {roomID: req.params.room})
});
io.on('connection' , (socket)=>{
socket.on('join-room' , (roomID, userID) => {
socket.join(roomID);
socket.broadcast.emit("user-connected" , userID);
socket.on("disconnect", () => {
socket.broadcast.emit("user-disconnected" , userID);
})
});
});
httpsServer.listen(5000 , ()=>{
console.log("Server running on port 5000");
})
peer-server.js
const { PeerServer } = require('peer');
const fs = require("fs");
const opts = {
key: fs.readFileSync('./certificates/key.pem', 'utf-8'),
cert : fs.readFileSync('./certificates/cert.pem', 'utf-8'),
}
const peerServer = PeerServer({
debug: true,
key: 'peerjs',
port: 5001,
path: '/myapp',
ssl: opts
});
peerServer.listen(() => {
console.log("Peer Server is listening on port 5001");
})
package.json
"name": "videocallingapp",
"version": "1.0.0",
"description": "Video Calling App",
"main": "app.js",
"scripts": {
"vcserver": "nodemon app.js",
"peerserver": "nodemon peer-server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.6",
"express": "^4.17.1",
"nodemon": "^2.0.7",
"peer": "^0.6.1",
"socket.io": "^4.0.1",
"uuid": "^8.3.2"
}
}
client-script.js
const socket = io('/')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, {
secure: true,
host: 'localhost',
port: '5001',
path: '/myapp'
})
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}
$(document).ready(function() {
debugger;
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
addVideoStream(myVideo, stream)
myPeer.on('call', call => {
call.answer(stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
})
socket.on('user-connected', userId => {
console.log("User Connected " + userId)
connectToNewUser(userId, stream)
})
})
socket.on('user-disconnected', userId => {
if (peers[userId]) peers[userId].close()
})
myPeer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
function connectToNewUser(userId, stream) {
const call = myPeer.call(userId, stream)
const video = document.createElement('video')
call.on('stream', function (userVideoStream) {
console.log("Called");
addVideoStream(video, userVideoStream)
})
call.on('close', function () {
console.log("Closed");
video.remove()
})
peers[userId] = call
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
})
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script>
const ROOM_ID = "<%= roomID %>"
</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="index.js" defer></script>
<title>Zoom Clone Video Chat</title>
<style>
#video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 300px;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="video-grid"></div>
</body>
</html>
Project Structure:
videocallapp
certificates
cert.pem
key.pem
node_modules
public
client-script.js
views
index.ejs
app.js
package.json
package-lock.json
peer-server.js

ExperimentalWarning: Conditional exports is an experimental feature"

I am getting this in error in node js while running a server. The error is as follows
"(node:17160) ExperimentalWarning: Conditional exports is an
experimental feature". This feature could change at any time"?
Full details can be found here
Any idea how to solve this? I am getting it in the terminal while running the nomemon server.js. My codes are as follows:
Here is mine:
Server.js
const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const { v4: uuidV4 } = require('uuid')
app.set('view engine', 'ejs')
app.use(express.static('public'))
app.get('/', (req, res) => {
res.redirect(`/${uuidV4()}`)
})
app.get('/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
io.on('connection', socket => {
socket.on('join-room', (roomId, userId) => {
socket.join(roomId)
socket.to(roomId).broadcast.emit('user-connected', userId)
socket.on('disconnect', () => {
socket.to(roomId).broadcast.emit('user-disconnected', userId)
})
})
})
server.listen(3000)
script.js
const socket = io('/')
const myPeer = new Peer(undefined, {
host:'/',
port:'3002'
})
myPeer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
socket.emit('join-room', ROOM_ID, 10)
socket.on('User-connected', userId => {
console.log('User-connected:' + userId)
})
Room.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Just Not a Document</title>
<script>
const ROOM_ID = "<%= roomId %>"
</script>
<script defer src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
<script src="/socket.io/socket.io.js" defer></script>
<script src="script.js" defer></script>
<style>
#video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 300px;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="video-grid"></div>
</body>
</html>

How do I choose a particular chunk in a stream to play with Axios and nodejs

So I created an express server to stream audio to an <audio> tag in the HTML document, The audio is streaming with no issues but I cannot select a particular point in the audio if I do so it stops playing unless I loaded the all the chunks to that point.
index.html
const axios = require("axios");
const httpAdapter = require("axios/lib/adapters/http");
const fs = require("fs");
const express = require("express");
const app = express();
const INPUT =
"https://dcs.megaphone.fm/ADV3183643348.mp3?key=c3dc25ae82cc18218902aa6a0675798a";
app.get("/audio", (req, res) => {
axios
.get(INPUT, { responseType: "stream", adapter: httpAdapter })
.then((Response) => {
const stream = Response.data;
res.set("content-type", "audio/mp3");
res.set("accept-ranges", "bytes");
res.set("content-length", Response.headers["content-length"]);
console.log(Response);
stream.on("data", (chunk) => {
res.write(chunk);
});
stream.on("error", (err) => {
res.sendStatus(404);
});
stream.on("end", () => {
res.end();
});
})
.catch((Err) => {
console.log(Err.message);
});
});
app.listen(4000, () => {
console.log("Server is running");
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node Streaming prototype</title>
</head>
<body>
<audio controls src="http://localhost:4000/audio"></audio>
</body>
</html>
I am new to Axios so I don't know how I can send a particular chunk and serve it on the audio tag.
Since you are using Axios, when responseType = 'stream' it returns you a stream.
All you need to do is to "connect" it to the response by putting axiosResponse.data.pipe(res); in the first then function, like below:
const axios = require("axios");
const httpAdapter = require("axios/lib/adapters/http");
const fs = require("fs");
const express = require("express");
const app = express();
const INPUT =
"https://dcs.megaphone.fm/ADV3183643348.mp3?key=c3dc25ae82cc18218902aa6a0675798a";
app.get("/audio", (req, res) => {
axios
.get(INPUT, { responseType: "stream", adapter: httpAdapter })
.then((axiosResponse) => {
const stream = axiosResponse.data;
res.set("content-type", "audio/mp3");
res.set("accept-ranges", "bytes");
res.set("content-length", Response.headers["content-length"]);
stream.pipe(res); // <---- pipe the stream to the response
})
.catch((Err) => {
console.log(Err.message);
});
});
app.listen(4000, () => {
console.log("Server is running");
});

Nodejs spawn remote tail and socket-io to client

I'm fairly new to Nodejs and I'm building an app that ssh to a remote machine and get a tail -f of a log file.
The lines of the log file I'm receiving I'm sending to the client via socket-io (ver. 2.0.3)
Now I'm facing a problem that when a second browser tries to tail a different log, the new log is sent to both of the browsers instead of only the one who made the request.
I'm not sure if it's a problem with my socket-io code or the child_process.
Here's the server:
const express = require('express'),
app = express(),
path = require('path'),
bodyParser = require('body-parser'),
logger = require('morgan'),
server = require('http').Server(app),
io = require('socket.io')(server),
spawn = require('child_process').spawn,
events = require('events'),
eventEmitter = new events.EventEmitter();
// Fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// Log the requests
app.use(logger('dev'));
// Serve static files
app.use(express.static(path.join(__dirname, '.')));
// Add a basic route – index page
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
io.on('connection', (socket) => {
console.log(`client connected ${socket.client.id}`);
eventEmitter.on('tail', (data) => {
socket.tail = spawn('ssh', ['root#' + 'quality-p.company.com', 'tail -f', data.service], { shell: true });
socket.tail.stdout.on('data', (data) => {
console.log(`got new data ${data.toString()}`);
socket.emit('newLine', {line: data.toString().replace(/\n/g, '<br />')});
});
});
});
app.get('/tail', (req, res) => {
eventEmitter.emit('tail', req.query);
res.sendStatus(200);
});
// Bind to a port
server.listen(3005, () => {
console.log('running on localhost:' + 3005);
});
Client:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(() => {
let socket = io();
socket.on('connect', () => {
console.log('connected');
});
socket.on('newLine', (data) => {
console.log(`new data: ${data.line}`);
$("#tailing").append(data.line);
});
$('#tail').click(() => {
$.get('/tail', {
service: $('#service').val()
});
});
});
</script>
<title>Title</title>
</head>
<body>
<select id="service">
<option id="tnet" value="/var/log/tnet">tnet</option>
<option id="consul" value="/var/log/consul">consul</option>
</select>
<button id="tail">tail</button>
<div id="tailing" style="background-color: antiquewhite;">
</div>
</body>
</html>
Server
const express = require('express'),
app = express(),
path = require('path'),
bodyParser = require('body-parser'),
logger = require('morgan'),
server = require('http').Server(app),
io = require('socket.io')(server),
spawn = require('child_process').spawn;
// Fix body of requests
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// Log the requests
app.use(logger('dev'));
// Serve static files
app.use(express.static(path.join(__dirname, '.')));
// Add a basic route – index page
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
var tails = {};
io.on('connection', (socket) => {
console.log(`client connected ${socket.client.id}`);
socket.on('tail', (data) => {
socket.join(data.service);
if (typeof tails[data.service] == "undefined") {
tails[data.service] = spawn('ssh', ['root#' + 'quality-p.company.com', 'tail -f', data.service], {
shell: true
});
tails[data.service].stdout.on('data', (data) => {
console.log(`got new data ${data.toString()}`);
io.to(data.service).emit('newLine', {
line: data.toString().replace(/\n/g, '<br />')
});
});
}
});
});
// Bind to a port
server.listen(3005, () => {
console.log('running on localhost:' + 3005);
});
Client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(() => {
let socket = io();
socket.on('connect', () => {
console.log('connected');
});
socket.on('newLine', (data) => {
console.log(`new data: ${data.line}`);
$("#tailing").append(data.line);
});
$('#tail').click(() => {
socket.emit('tail', {
service: $('#service').val()
});
});
});
</script>
<title>Title</title>
</head>
<body>
<select id="service">
<option id="tnet" value="/var/log/tnet">tnet</option>
<option id="consul" value="/var/log/consul">consul</option>
</select>
<button id="tail">tail</button>
<div id="tailing" style="background-color: antiquewhite;">
</div>
</body>
</html>

Resources