Socketio undefined results - node.js

a few days ago I tried to train with react by creating a real-time chat application, but I'm a bit lost in the io socket, I can't send a message or notification on a specific user, I get an "undefined" error, here is my socket io code:
I tried to retrieve the user with the id as receiverId but socket io returns me undefined
about this function:
socket.on("friendRequest", ({ senderId, receiverId }) => { const receiver = getUser(receiverId); console.log(receiver) });
How can I fix this error,
thank you very much
And sorry for my English,
const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const cors = require('cors');
const PORT = process.env.PORT || 5000;
const router = require('./router');
//const { Socket } = require('dgram');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(router);
app.use(cors());
let users = [];
const addUser = (userId, socketId) => {
!users.some((user) => user.userId === userId) &&
users.push({ userId, socketId });
};
const removeUser = (socketId) => {
users = users.filter((user) => user.socketId !== socketId);
};
const getUser = (userId) => {
return users.find((user) => user.userId === userId);
};
io.on('connect', (socket) => {
console.log("a user connected.");
socket.on("addUser", (userId) => {
addUser(userId, socket.id);
io.emit("getUsers", users);
});
socket.on("sendNotification", ({ senderId, receiverId, type }) => {
const receiver = getUser(receiverId);
io.to(receiver.socketId).emit("getNotification", {
senderId,
type,
});
});
socket.on("friendRequest", ({ senderId, receiverId }) => {
const receiver = getUser(receiverId);
console.log(receiver)
});
socket.on("sendText", ({ senderId, receiverId, text }) => {
const receiver = getUser(receiverId);
io.to(receiver.socketId).emit("getText", {
senderId,
text,
});
})
socket.on("disconnect", () => {
console.log("User Disconnected", socket.id);
removeUser(socket.id);
io.emit("getUsers", users);
});
});
app.use(router);
server.listen(PORT,() => console.log('Server has started on port ${PORT}'));```

Related

My socket event don't trigger when I am emit it in Nodejs

My socket event doesn't trigger when I emit it in Nodejs, I know it because I don't see "Pizza" in my console.
This is my code:
const express = require("express");
const cors = require("cors");
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
});
app.use((req, res, next) => {
req.io = io;
next()
})
app.use(cors());
io.on('connection', (socket) => {
socket.on("dummy_event", (data) => {
console.log(`Socket 🍕`); // I don't see this message in my console
if(!data.name) return;
})
});
app.get("/socket_test", (req, res) => {
req.io.emit("dummy_event", {name: "pizza"})
return res.json({data: 'dummy text'})
})
server.listen(4000, () => {
console.log(`Server Started on Port 4000`);
})

export a function inside socket connection

I have created a socket server as shown below.
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {cors:{origin:'*'}})
const mongoose= require("mongoose")
const port = process.env.PORT || 4002;
server.listen(port, ()=>{
console.log(`Listening on port ${port}......`)
})
onlineUsers = [];
const addNewUser = (userId, socketId)=>{
!onlineUsers.some((user)=>user.userId === userId) &&
onlineUsers.push({userId,socketId})
}
const removeUser= (socketId) =>{
onlineUsers = onlineUsers.filter((user)=> user.socketId!==socketId)
}
const getUser = (userId)=>{
return onlineUsers.find(user=>user.userId ===userId)
}
io.on("connection", (socket=> {
console.log("User connected:", socket.id);
socket.on("disconnect",()=>{
removeUser(socket.id)
})
socket.on("newUser",(userId)=>{
addNewUser(userId, socket.id)
})
export function handleMessaging (userId,clientID,messageId )
{
const receiver = getUser(userId);
if(receiver)
{
io.to(receiver.socketId).emit("sendMessage", {data:"working properly"});
return true;
}
else return false
}
}));
I want to export the function handle messaging so that I can use it inside the API like (shown below) to see if a user is online and if yes, send a message.
But as someone new to programming, I can't figure out how to export handle messaging the proper way. I tried to use export but its telling me "Modifiers cannot appear here".
router.post('/:companyId' async (req, res) => {
const {userId,clientId,messageId} = req.body
handleMessaging (userId,clientID,messageId )
{
//do xyz
}
}

WebSocket (Socket.io) connection Error - failed: Connection closed before receiving a handshake response

I have spent all day figuring out and searching for solution online for error
WebSocket connection to 'wss://localhost/myapp/peerjs?key=peerjs&id=5c70da87-62c1-41dd-b1b1-e7aea5acc09b&token=j4n0nprnu6' failed: Connection closed before receiving a handshake response
I am developing this nodejs app on express server. My express server where I initialize PeerServer along with it:
// Dependencies
const express = require('express')
const app = express()
const httpPort = process.env.PORT || 80
const httpsPort = 443
const { ExpressPeerServer } = require('peer')
const path = require('path')
const http = require('http')
const https = require('https')
const fs = require('fs')
// Certificate & credentials
const privateKey = fs.readFileSync(path.join(__dirname, 'certs', 'key.pem'))
const certificate = fs.readFileSync(path.join(__dirname, 'certs', 'cert.pem'))
const credentials = {
key: privateKey,
cert: certificate
}
const mainServer = http.createServer(app).listen(httpPort, () => { console.log('Main Server listening to port ' + httpPort) })
const httpsServer = https.createServer(credentials, app).listen(httpsPort, () => { console.log('Peer Server listening to port ' + httpsPort) })
const peerServer = ExpressPeerServer(mainServer, {
debug: true,
path: '/myapp'
})
//app.use('peerjs', peerServer)
app.use(peerServer)
const io = require('socket.io')(httpsServer)
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 })
//console.log('Room Created / Joined')
})
io.on('connection', (socket) => {
//console.log('IO Connectedd')
socket.on('join-room', (roomId, userId) => {
console.log(roomId, userId)
socket.join(roomId)
socket.to(roomId).emit('user-connected', userId)
socket.on('disconnect', () => {
socket.to(roomId).emit('user-disconnected', userId)
})
})
})
And below is my client side code
const socket = io('/')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, {
host: '/',
port: '443',
path: '/myapp'
})
const ownVideo = document.createElement('video') // Own Video
ownVideo.muted = true
const peers = {}
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
addVideoStream(ownVideo, stream)
myPeer.on('call', call => { // On Receiving Other Persons Call
call.answer(stream) // Send Video Stream On Answer
const video = document.createElement('video')
call.on('stream', userVideoStream => { // Send Back Video Stream On Stream
addVideoStream(video, userVideoStream)
})
})
socket.on('user-connected', userId => { // Allow Self To Be Connected To Others
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) // We Connect To Other User
const video = document.createElement('video')
call.on('stream', userVideoStream => { // Other User Connects To Us
addVideoStream(video, userVideoStream)
})
call.on('close', () => { // Other User Disconnects
video.remove()
})
peers[userId] = call
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
I am new to nodejs and couldn't find any solution online for it.
Please help!!
Your code needed some rearrangement, once done, it worked fine for me on W10, VSC and Chrome Version 91.0.4472.164 (Official Build) (64-bit). It is simpler to include my working code rather than trying to explain each change. I will include here the script.js and server.js files (working) and the whole code working workspace in github here for anybody to use. I want to emphasize that you do want to call the peer.on('call'.... event handler ahead of waiting for any promises, to make sure your remote client has this handler ready before receiving a call from the originator client, that was not part of the issue that created the error you asked about.
CLIENT SIDE:
const socket = io('/')
const videoGrid = document.getElementById('video-grid')
let Peer = window.Peer;
const peer = new Peer({
host: '/',
path: '/peerjs',
debug: 3,
port: 80,
secure: false,
});
console.log('***Created peer instance, userId: ' + peer.id)
// Function to obtain stream and then await until after it is obtained to go into video chat call and answer code. Critical to start the event listener ahead of everything to ensure not to miss an incoming call.
const ownVideo = document.createElement('video') // Own Video
ownVideo.muted = true
const peers = {}
// On Receiving Other Persons Call
peer.on("call", async (call) => {
try {
let stream = null;
stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
call.answer(stream) // Send Video Stream On Answer
const video = document.createElement('video');
// Send Back Video Stream On Stream
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream);
});
}
catch (err) {
/* handle the error */
console.log('*** ERROR returning the stream: ' + err);
}
});
(async () => {
try {
let stream = null;
stream = await navigator.mediaDevices.getUserMedia(
{
audio: true,
video: true,
});
if (stream != undefined) {
addVideoStream(ownVideo, stream);
console.log('added own Video stream');
} else {
console.log('You can only access your audio/video media streams over https');
alert('Sorry retry using https, for security reasons Google Media blocks access to your video stream over unsecure http connections');
}
} catch (err) {
/* handle the error */
console.log('*** ERROR returning the stream: ' + err);
alert('Sorry retry using https, for security reasons Google Media blocks access to your video stream over unsecure http connections');
}
})();
socket.on('user-connected', userId => { // Allow Self To Be Connected To Others
console.log('User Connected: ' + userId)
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
connectToNewUser(userId, stream)
})
})
socket.on('user-disconnected', userId => {
if (peers[userId]) peers[userId].close()
})
peer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
function connectToNewUser(userId, stream) {
const call = peer.call(userId, stream) // We Connect To Other User
const video = document.createElement('video')
call.on('stream', userVideoStream => { // Other User Connects To Us
addVideoStream(video, userVideoStream)
})
call.on('close', () => { // Other User Disconnects
video.remove()
})
peers[userId] = call
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
SERVER SIDE:
// Dependencies
const express = require('express')
const app = express()
const httpPort = process.env.PORT || 80
const httpsPort = 443
const { ExpressPeerServer } = require('peer')
const path = require('path')
const http = require('http')
const https = require('https')
const fs = require('fs')
const certs = `C:/Users/spine/Documents/Personal Files/ArduinoData/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/examples/BearSSL_Server/`
// Certificate & credentials
const privateKey = fs.readFileSync(path.join(certs, 'key.pem'))
const certificate = fs.readFileSync(path.join(certs, 'cert.pem'))
const credentials = {
key: privateKey,
cert: certificate
}
const mainServer = http.createServer(app).listen(httpPort, () => { console.log('Main Server listening to port ' + httpPort) })
const httpsServer = https.createServer(credentials, app).listen(httpsPort, () => { console.log('Peer Server listening to port ' + httpsPort) })
const peerServer = ExpressPeerServer(mainServer, {
debug: true,
ssl: {},
})
app.use('/peerjs', peerServer)
// app.use(peerServer)
const io = require('socket.io')(httpsServer,{
// const io = require('socket.io')(mainServer, {
cors: {
origin: "*",
},
});
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 })
//console.log('Room Created / Joined')
})
io.on('connection', (socket) => {
//console.log('IO Connectedd')
socket.on('join-room', (roomId, userId) => {
console.log(roomId, userId)
socket.join(roomId)
socket.to(roomId).emit('user-connected', userId)
socket.on('disconnect', () => {
socket.to(roomId).emit('user-disconnected', userId)
})
})
})
I got it working with following cod on server side. Though I was able to get it work over SSL only.
const express = require('express')
const app = express()
const httpPort = process.env.PORT || 80
const httpsPort = 443
const { ExpressPeerServer } = require('peer')
const path = require('path')
const http = require('http')
const https = require('https')
const fs = require('fs')
// Certificate & credentials
const privateKey = fs.readFileSync(path.join(__dirname, 'certs', 'key.pem'))
const certificate = fs.readFileSync(path.join(__dirname, 'certs', 'cert.pem'))
const credentials = {
key: privateKey,
cert: certificate
}
const httpsServer = https.createServer(credentials, app).listen(httpsPort, () => { console.log('Peer Server listening to port ' + httpsPort) })
const peerServer = ExpressPeerServer(httpsServer, {
debug: true,
path: '/myapp'
})
app.use(peerServer)
const io = require('socket.io')(httpsServer, {
forceNew: true,
transports: ["polling"],
})
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.broadcast.to(roomId).emit('user-connected', userId)
socket.on('disconnect', () => {
socket.broadcast.to(roomId).emit('user-disconnected', userId)
})
socket.on('text-message', message => {
socket.broadcast.to(roomId).emit('text-message-received', message)
})
socket.on('system-stream-updated', remoteUserId => {
socket.broadcast.to(roomId).emit('new-remote-stream', remoteUserId)
})
})
})

peerjs event 'call' some times not fire up

I setup my local server.
const fs = require('fs');
const {PeerServer} = require('peer');
const peerServer = PeerServer({
port: 3001,
debug: false,
secure: true,
path: '/',
ssl: {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
}
});
peerServer.on('connection', (_client) => {
console.log('Client connects');
});
peerServer.on('disconnect', (_client) => {
console.log('Client disconnects');
});
I use also local express server
const fs = require('fs');
const key = fs.readFileSync('./key.pem');
const cert = fs.readFileSync('./cert.pem');
const express = require('express');
const app = express();
const server = require('https').createServer({key: key, cert: cert },app);
const io = require('socket.io')(server);
const {v4: uuid} = require('uuid');
require('./room')(io)
server.listen(3000,'192.168.1.30');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', ((req, res) => {
res.redirect(`${uuid()}`)
}))
app.get('/:room', ((req, res) => {
res.render('room', {roomId: req.params.room})
}))
function socketInit(io) {
io.on('connection', socket => {
socket.on('join-room', (roomId, userId) => {
socket.join(roomId)
socket.to(roomId).broadcast.emit('user-connected', userId)
socket.on('user_disable_camera', (userId) => {
socket.to(roomId).broadcast.emit('user_disable_camera', userId)
});
socket.on('user_enable_camera', (userId) => {
socket.to(roomId).broadcast.emit('user_enable_camera', userId)
})
// socket.on('screen_share_start', (userId) => {
// socket.to(roomId).broadcast.emit('user-disconnected', userId)
// });
socket.on('screen_share_stop', (userId) => {
socket.to(roomId).broadcast.emit('screen_share_stop', userId)
});
socket.on('disconnect', () => {
socket.to(roomId).broadcast.emit('user-disconnected', userId)
})
})
});
}
module.exports = socketInit
In my html file
const myPeer = new Peer(undefined, {
host: '/',
path: '/',
secure: true,
port: '3001'
});
myPeer.on('error', e => {
console.log('my peer error', e);
myPeer.reconnect();
})
...grab media stream...
addVideo(document.getElementById('me'), myVideo, stream);
myPeer.on('call', call => {
call.answer(stream);
peers[call.peer] = call;
console.log('call', call);
const video = document.createElement('video');
video.id = call.peer;
call.on('stream', userVideoStream => {
addVideo(videoList, video, userVideoStream)
});
})
socket.on('user-connected', userId => {
console.log('user conected', userId);
connectToNewUser(userId, stream);
})
function connectToNewUser(userId, stream) {
try {
const call = myPeer.call(userId, stream);
peers[userId] = call
console.log('connectToNewUser', stream, userId, peers, call);
const video = document.createElement('video');
video.id = userId;
call.on('stream', videoStream => {
addVideo(videoList, video, videoStream)
});
call.on('close', () => {
video.remove();
});
} catch (e) {
console.log('errrrrrrrrr', e);
}
}
Some times when i connect my computer and other computer same network, and https is present myPeer.on('call'... not fire up (2 users). When I open new tab(must be at least 3 users) with same room Id it some times is been called and then video is showing properly. Can some one point me in direction were is error ?

UserId undefined-socket io /node js

I'm trying to use socket.io for a while but I faced some problem in emit data to client side
the code works perfectly but I keep getting not defined for userId on the client side see below
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) => {
console.log(roomId, userId)
socket.join(roomId)
socket.to(roomId).broadcast.emit('connect', userId)
console.log(userId)
})
})
server.listen(3000)
client
const socket = io('/')
const $events = document.getElementById('events');
const newItem = (content) => {
const item = document.createElement('li');
item.innerText = content;
return item;
};
socket.emit('join-room', ROOM_ID, 10) // 10 here is the userId
socket.on('connect', function(userId) {
$events.appendChild(newItem('user connected:' + userId)); // the userId ==== undefined
})
the is the error
Update your server file like shown below
io.on('connection', socket => {
socket.on('join-room', (roomId, userId) => {
console.log(roomId, userId)
socket.join(roomId)
socket.to(roomId).emit('connect', userId)
console.log(userId)
})
})

Resources