How to resolve server error in Socket.io? - node.js

I am creating a web application, using socket.io . A Server error occurred while connecting to the server. We found out that the error is in the backend. What could be written incorrectly here? Code:
const path = require('path');
const express = require('express');
const app = express();
const fs = require("fs");
var privateKey = fs.readFileSync('path').toString();
var certificate = fs.readFileSync('path').toString();
const http = require('https').Server({key:privateKey,cert:certificate}, app);
const io = require('socket.io')(http);
const port = 9998;
const debug = true;
var connectedArray = new Array()
const delay = 60 * 1000
const mysql = require('mysql2');
const db = mysql.createConnection({
host: 'localhost',
user: 'user_name',
password: 'user_password',
database: 'database',
});
io.on('connection', (socket) => {
socket.on('register', msg => {
console.log("User registered")
connectedArray.push({
connectmessage: msg,
socket: socket,
})
})
socket.on('disconnect', () => {
if (debug) console.log('User disconnected')
})
})
app.use(express.static(path.resolve(__dirname, 'static')))
app.get('/', (req, res) => {
res.sendFile('./index.html')
})
http.listen(port, () => {
console.log(`Server started listening on port ${port}...`)
})
P.S: The problem began to arise after binding the domain
P.S 2: I have two sites on server, on different Apache virtual hosts
P.S 3: I am using https

Related

Postman: Connect ECONNREFUSED 127.0.0.1:5005

I have developed an API endpoint. It was working fine before. Unfortunately the project folder got corrupted (I recreated the files db.js and server.js). But now when I try to fetch data from API, I'm getting:
"connect ECONNREFUSED 127.0.0.1:5005"
The URL I'm using is localhost:
And my server is running on the same port i.e. 5005:
Can someone please elaborate what can be the problem? My hunch is that when I recreated the files I may have missed something:
db.js:
const mongoose = require('mongoose');
const userName = "myUsername"
const password = "myPassword"
const dbName = "comfyRooms"
const dbURL = `mongodb+srv://${userName}:${password}#mongo-cluster.damzf.mongodb.net/${dbName}?authSource=admin&replicaSet=atlas-s7z01e-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true`
mongoose.connect(dbURL, {useUnifiedTopology: true, useNewUrlParser: true})
let connection = mongoose.connection
connection.on('error', () => {
console.log('Unable to connect to MongoDB')
})
connection.on('connected', () => {
console.log("MongoDB connection established :)")
})
module.exports = mongoose
server.js
const express = require('express')
const app = express()
const dbConfig = require('./db')
const roomsRoute = require('./routes/roomsRoute')
app.use('/api/rooms', roomsRoute)
const port = process.env.PORT || 5005
app.listen(() => {
console.log("Node JS server listening on port " + port)
})
roomsRoute.js:
const express = require('express');
const router = express.Router();
const Room = require('../models/rooms');
router.get('/getallrooms', async (req, res) => {
try {
const rooms = await Room.find({});
return res.send(rooms);
} catch (error) {
return res.status(400).json({message: error});
}
});
module.exports = router;
I have attached the important files. Please let me know if any other information is missing. Thanks!
You are not passing the port variable to the listen function, you are just logging it
app.listen(() => {
console.log("Node JS server listening on port " + port)
})
This should work
app.listen(port, () => {
console.log("Node JS server listening on port " + port)
})

Issue with scaling my socket io node app with Redis

After implementing the scaling code in my app with Redis the receipt at the client-side was unable to receive the emits from the socket server.
I tried using the sample code in the following package page
https://www.npmjs.com/package/#socket.io/redis-adapter
read the inspiration concept from the given example
https://medium.com/containers-on-aws/scaling-a-realtime-chat-app-on-aws-using-socket-io-redis-and-aws-fargate-4ed63fb1b681
The library used in this was deprecated, so I took the new version of the library and tried the code.
I have attached the code used for the app
const app = express();
const { createClient } = require('redis');
const redisAdapter = require('#socket.io/redis-adapter');
const server = require('http').createServer(app);
const io = require('socket.io')(server);
app.get('/', (req, res) => {
const arr = Array.from(io.sockets.adapter.rooms);
const filtered = arr.filter(room => !room[1].has(room[0]));
const rooms = filtered.map(i => (i[0]));
res.send({ rooms });
});
let pubClient;
(async () => {
pubClient = createClient({ host: 'localhost', port: 6379 });
pubClient.on('error', (err) => console.log('Redis Client Error', err));
await pubClient.connect();
const subClient = pubClient.duplicate();
io.adapter(redisAdapter(pubClient, subClient));
})();
// const pubClient = createClient({ host: 'localhost', port: 6379 });
io.on('connection', (socket) => {
socket.on('join', (room) => {
socket.join(room)
console.log(`Room to be joined ${room}`);
console.log(io.sockets.adapter.rooms);
console.log(io.sockets.adapter.sids);
})
socket.on('message', (message) => {
console.log(message)
const status = socket.emit(message.to, message.content)
console.log(status)
})
});
const port = 3000
server.listen(port, () => {
console.log(`Server listening to port ${port} with process id ${process.pid}`);
});```
Iam not sure if I miss some thing while scaling the app.Please do share your idea on this.

socket io on connection not firing

I'm using socket.io-redis and it doesn't seem like it's connected... I tried with my client application and with socketio-client-tool, but I'm not getting any connections. here's my code:
index.js
const express = require('express');
const app = express();
const server = require('http').createServer(app);
require('./socket/socket')(server);
module.exports = server.listen(4000, () => logger.info(`Listening on port 4000`));
socket.js
module.exports = function (server) {
const _io = io(server);
const redisConnection = redisAdapter({ host: 'localHost', port: 6379 });
logger.info('connected to redis');
_io.adapter(redisConnection);
logger.info(`connected to socket.io`);
_io.on('connection', (socket) => {
console.log('a user connected');
});
};
I'm using ngrok to access the backend. Not sure if that has to do...

SocketIO – connection issues and clustering

I have a really simple NodeJS app that I want to run on Heroku. This is how the index.js file looks like:
Server (port 3030)
const http = require('http');
const os = require('os');
const express = require('express')
const throng = require('throng'); // For cluster management
const { port, env, isProduction } = require('./config/vars');
const SocketIO = require('socket.io');
// Setting up a simple express app and wrapping it with http server
const setupServer = () => {
const app = express();
app.use(express.static(path.join(__dirname, '../public')));
const server = http.createServer(app);
return server;
};
const setupSocket = (server) => {
const io = new SocketIO(server);
io.on('connection', (socket) => {
console.log(`[Socket] Connection established: ${socket.id}`);
socket.on(msg.rooms.join, (room) => {
socket.join(room);
socket.to(room).emit(msg.rooms.joined);
console.log(`[Socket] User ${socket.id} joined '${room}' room`);
});
socket.on('disconnect', () => {
console.log(`[Socket] Distonnected: ${socket.id}`);
});
});
return io;
};
const WORKERS = (() => {
if (!isProduction) return 1;
return process.env.WEB_CONCURRENCY || os.cpus().length;
})();
async function master() {
console.log(`Preparing ${WORKERS} workers...`);
console.log('Master started.');
}
// There should be one server instance for each worker
const start = () => {
const server = setupServer(); // Returns and `http` server instance
const socket = setupSocket(server);
server.listen(port, async () => {
Logger.info(`Server – listening on port ${port}`);
});
return server;
};
const instance = throng({
workers: WORKERS,
lifetime: Infinity,
start,
master,
});
module.exports = instance;
Client (port 3000)
const setupSocket = ({ room }) => {
// Fallback if already setup
if (window.sockets[room]) {
return window.sockets[room];
}
const socket = io('http://localhost:3030');
socket.on('connect', () => {
console.log('[Socket] Connection established!', socket.id);
socket.emit('room.join', room);
});
socket.on('room.joined', () => {
console.log(`[Socket] Connected to ${room} room!`);
});
window.sockets[key] = socket;
return socket
};
The problem – the connection is sometimes established properly but most of the time I get an error
Error during WebSocket handshake: Unexpected response code: 400
What might be the problem here? Is it because I have it on two different ports or is it because of the clusters?
I've tried removing the throng part of the code, and just calling start() method without any cluster setup, but the problem remains :(
why would you use http module? The server instance that you send in the socketIO constructor should be the return object of the expressInstance.listen
Something more like this:
const express= require('express')
const app = express()
const socketio = require('socket.io')
app.use(express.static(__dirname + '/public'))
const server = app.listen('4000',()=>{
console.log('Listening to port:4000')
})
const io = socketio(server)
io.on('connect',(socket)=>{
socket.broadcast.emit('new_user')
socket.on('new_message',(message)=>{
io.emit('new_message',message)
})
})
source code: socket-io chat

How to send message to frontend in case of MongoDb connection Failed

Is there any way to send error to frontend on mongoDb connection error.I had tried in a different different way but I didnt get a solution.
var express = require('express');
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
app.get('/',function(req,res){
res.send('NOT Connected....')
});
});
You can use web sockets to push this information to the UI.
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').createServer(app);
const io = require('../..')(server);
const port = process.env.PORT || 3000;
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
socket.emit('mongodb-failed', error)
});
});
server.listen(port, () => {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
// when socket emits 'mongodb-connection-failed', this listens and executes
socket.on('mongodb-failed', (data) => {
// we tell the client to execute 'new message'
socket.broadcast.emit('mongodb-connection-failed', {
errorDetails: data
});
});
});
now at client side:
var socket = io();
socket.on('mongodb-connection-failed', () => {
console.log('you have been disconnected');
//do more whatever you want to.
});
This above example is using socket.io.
You can use any web socket library, see more here

Resources