javascriptnode.jsexpresssocket.iongrok

Socket.io connection error net::ERR_CONNECTION_REFUSED when accessing from different devices


I've encountered an error with other people's computers, they can't access my little test chatting application, and incounter this error when attempting to connect:

localhost:3000/socket.io/?EIO=4&transport=polling&t=Oi2Ko0C:1
       
       
        Failed to load resource: net::ERR_CONNECTION_REFUSED
localhost:3000/socket.io/?EIO=4&transport=polling&t=Oi2KorJ:1

My socket.io version is: 4.7.2 and I'm port fowarding with ngrok, i've tried localtunnel, same errors as ngrok. Not sure why I'm also getting strict-origin-when-cross-origin for some reason I even have my origin set as "*" so it's very weird. Here is my code:

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
    cors: {
        origin: "*",
        methods: ["GET", "POST"]
    },
    transports: ['websocket']
});

mongoose.connect('notgonnagiveyouthat', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

const PORT = 3000;

const userSchema = new mongoose.Schema({
    username: String,
    password: String
});

const User = mongoose.model('User', userSchema);

const messageSchema = new mongoose.Schema({
    username: String,
    content: String,
    timestamp: {
        type: Date,
        default: Date.now
    }
});

const Message = mongoose.model('Message', messageSchema);

passport.use(new LocalStrategy(async (username, password, done) => {
    try {
        const user = await User.findOne({ username: username });
        if (!user) {
            return done(null, false, { message: 'Username not registered' });
        }
        const isMatch = await bcrypt.compare(password, user.password);
        if (isMatch) {
            return done(null, user);
        } else {
            return done(null, false, { message: 'Incorrect password' });
        }
    } catch (err) {
        return done(err);
    }
}));

passport.serializeUser((user, done) => {
    done(null, user.id);
});

passport.deserializeUser(async (id, done) => {
    try {
        const user = await User.findById(id);
        done(null, user);
    } catch (err) {
        done(err);
    }
});

app.use(session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
}));

app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));

app.get('/login', (req, res) => {
    res.sendFile(__dirname + '/login.html');
});

app.post('/login', passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect: '/login'
}));

app.get('/signup', (req, res) => {
    res.sendFile(__dirname + '/signup.html');
});

app.post('/signup', async (req, res) => {
    const { username, password } = req.body;
    const user = await User.findOne({ username });
    if (user) {
        return res.redirect('/signup');
    }
    const hashedPassword = await bcrypt.hash(password, 10);
    const newUser = new User({
        username,
        password: hashedPassword
    });
    await newUser.save();
    res.redirect('/login');
});

app.get('/', (req, res) => {
    if (!req.isAuthenticated()) {
        return res.redirect('/login');
    }
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', async (socket) => {
    console.log('User connected');
    try {
        const messages = await Message.find().sort({ timestamp: -1 }).limit(10).exec();
        socket.emit('previousMessages', messages.reverse());
    } catch (err) {
        console.error("Error fetching messages:", err);
    }
    socket.on('sendMessage', async (data) => {
        const message = new Message({
            username: data.username,
            content: data.content
        });
        try {
            await message.save();
            io.emit('receiveMessage', message);
        } catch (err) {
            console.error("Error saving message:", err);
        }
    });
    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

server.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

Solution

  • That is because their application is trying to connect to "localhost" that resolves to 127.0.0.1, which is their local machine address. You want their client app to try to connect to your machine IP address instead. To find your local IP address you can follow this question: https://apple.stackexchange.com/questions/20547/how-do-i-find-my-ip-address-from-the-command-line