Socket.io doesn't work with on event ("connection") - node.js

i want to use socket-io in my project and i established it on the server (node-js) and
the client (react) but it seems doesn't work fine and in console on the server i can't see user connected when user connected.
app.js (server):
const express = require("express");
const app = express();
const PORT = process.env.PORT || 5000;
(async () => {
await mongoConnect(error => {
if (error) {
console.log(error);
} else {
const server = app.listen(PORT, () =>
console.log(`server is running on ${PORT} port`)
);
const io = require("./utils/socket-io/socket-io").initialSocket(server);
io.on("connection", socket => {
console.log("user connected");
});
}
});
})();
socket-io.js (server):
const socketIo = require("socket.io");
let io;
module.exports = {
initialSocket: server => {
io = socketIo(server);
return io;
},
getIo: () => {
if (!io) {
throw new Error("no connection to socket-io");
}
return io;
}
};
posts.js (client):
import socketIo from "socket.io-client";
useEffect(() => {
socketIo("http://localhost:5000");
}, [socketIo]);

Edit your app.js to this
const http = require('http');
const socketio = require('socket.io');
const app = express();
const server = http.createServer(app); // This is going to allow us to create a new web server for express and we're going to it to our express application
const io = socketio(server); // Configure socketio to work with a given server
// Now the server supports websockets
(async () => {
await mongoConnect(error => {
...
else {
io.on("connection", socket => {
console.log("user connected");
});
server.listen(port, () => console.log(`Server is up on port ${port}`));
}
});
})();

Related

Socket.IO and Electron can't emit or receive

I have an Electron project initiated with VueCLI and a litle nodejs socket.io server, here's the server's file :
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const {
userJoin,
getCurrentUser,
userLeave,
getRoomUsers,
users
} = require('./utils/users');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
// Set static folder
app.use(express.static(path.join(__dirname, 'public')));
// Run when client connects
io.on('connection', socket => {
console.log(`Connected tp ${socket.id}`)
app.get('/send-file', (req, res, next) => {
res.send('Sent')
})
socket.on('joinRoom', (args)=>{
console.log('joinroom')
})
// Runs when client disconnects
socket.on('disconnect', () => {
const user = userLeave(socket.id);
});
});
const PORT = process.env.PORT || 7575;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
And here's my preload.js file :
const io = require('socket.io-client');
window.socket = io('http://localhost:7575');
window.socket.on('welcome', () => {
console.log('on welcome : welcome received renderer'); // displayed
window.socket.emit('test')
});
window.socket.on('error', (e) => {
console.log(e); // displayed ?
});
window.socket.on('ok', () => {
console.log("OK received renderer"); // displayed
});
window.socket.on('connect', () => {
console.log("connected renderer"); // displayed
window.socket.emit('test');
});
And here's my createWindow function:
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 700,
height: 600,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
enableRemoteModule: true,
preload: path.join(__dirname, 'preload.js')
}
})
win.setMenu(null)
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
}
The connection is made between the client and the server, because the console.log(Connected tp ${socket.id}) show a different socket ID everytime, but on my compenent, when I call the emit function nothing happens : window.socket.emit('joinRoom', {email:this.email, apikey:this.apikey})
And I can't event receive message on the client side, I've tested the server and everything works fine on a normale browser, but on my electron application can't emit or receive messages.
Is this related to my electron application?
Here's how I did it -
Server side:
const express = require('express')
const app = express()
// middlewares
app.use(express.static('public'))
// routes
app.get('/', (req, res) => {
res.render('index')
})
server = app.listen(7575, () => {
console.log("Server started");
})
//socket.io instantiation
const io = require("socket.io")(server)
//listen on every connection
io.on('connection', (socket) => {
console.log('New user connected');
//listen on "test"
socket.on('test', (data) => {
var username = data.username;
})
})
Client side:
socket = io.connect('http://localhost:7575')
socket.emit('test', {username: 'username'})

Can't get React + socket.io to work on Heroku

I'm trying to set up a simple socket.io echo server on Heroku using Express and React. The server returns the React site from the build folder, then listens for incoming messages using onAny(). Everything works fine locally, but when deployed to Heroku none of the client-emitted messages are going through after the connection has been established.
I've used Heroku's guide as well as create-react-app and this Medium article as my starting points, and did make sure to turn on http-session-affinity as the Heroku guide said to.
Currently, the React client is set up to emit a fixed message through the onclick handler of a <span>.
Here's the contents of server.js:
'use strict';
const path = require('path');
const express = require('express');
const socketIO = require('socket.io');
const PORT = process.env.PORT || 3000;
const app = express()
.use(express.static('build'))
.listen(PORT, () => console.log(`Listening on ${PORT}`));
const io = socketIO(app);
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('disconnect', () => console.log('Client disconnected'));
socket.onAny((type, data) => {
console.log('Received:');
console.log(data);
socket.emit('echo', data);
});
});
And here is the client-side React hook that establishes the connection and emits the messages, where I replace [app-name] with the Heroku app name:
import { useEffect, useRef, useState } from "react";
import socketIOClient from "socket.io-client";
const NEW_CHAT_MESSAGE_EVENT = "newChatMessage";
// const SOCKET_SERVER_URL = 'localhost:3000';
const SOCKET_SERVER_URL = 'wss://[app-name].herokuapp.com/sockjs-node';
const useChat = (roomId) => {
const [messages, setMessages] = useState([]);
const socketRef = useRef();
useEffect(() => {
socketRef.current = socketIOClient(SOCKET_SERVER_URL, {
query: { roomId },
});
socketRef.current.on(NEW_CHAT_MESSAGE_EVENT, (message) => {
console.log(message);
const incomingMessage = {
...message,
ownedByCurrentUser: message.senderId === socketRef.current.id,
};
setMessages((messages) => [...messages, incomingMessage]);
});
return () => {
socketRef.current.disconnect();
};
}, [roomId]);
const sendMessage = (messageBody) => {
console.log('sendMessage()');
socketRef.current.emit(NEW_CHAT_MESSAGE_EVENT, {
body: messageBody,
senderId: socketRef.current.id,
});
};
return { messages, sendMessage };
};

How to fixed websocket invalid frame header?

I am running backend(nodejs server) at port 5000. And running frontend at reactjs.
Peerjs also not connecting. Everytime it throwing
WebSocket connection to
'ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=RpMvIyH3kAFbQpntAAAA'
failed: Invalid frame header
I want keep frontend and backend in separate server.
Frontend(React)
try {
socket = io.connect('http://localhost:5000/');
} catch (e) {
console.error(e)
}
BackEnd(Nodejs)
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const { v4: uuidv4 } = require('uuid');
const { ExpressPeerServer } = require('peer');
const PORT = process.env.PORT || 5000;
const peerServer = ExpressPeerServer(server, {
debug: true
});
app.use('/peerjs', peerServer);
io.on('connection', (socket) => {
socket.on('join-room', (roomId, userId) => {
socket.join(roomId);
socket.to(roomId).broadcast.emit('user-connected', userId);
socket.on('message', message => {
io.to(roomId).emit('createMessage', message);
})
socket.on('disconnect', () => {
socket.to(roomId).broadcast.emit('user-disconnected', userId)
})
})
});
server.listen(PORT, () => {
console.log(`Server has started on port ${PORT}`);
});

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

I cannot get new connection

I am having a problem with socket.io
There is no way I can see in the console.log when i try to connect to localhost:8080, the server is working but my socket which is properly bind to the server never says "new connection".
Can you help me please ?
import express from "express";
import socket from "socket.io";
const app = new express();
const server = app.listen(`${process.env.PORT_API}`, () => {
console.log(`Server is running on port ${process.env.PORT_API}`);
});
const io = new socket(server);
io.on('connection', (socket) => {
console.log("new connection");
})
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => {
console.log("new connection");
});
server.listen(`3000`, () => {
console.log(`Server is running on port 3000`);
});
Reference: Link here

Resources