Socket connection is not working while using express with next.js - node.js

I have a problem with using socket.io in my application.
I use Next.js, Express.js, socket.io, socket.io-client
When I run Next.js server and Express server then access the page, socket is immediately connected. But when I post to /webhook/notify from other server socket.emit("notify", req.body); does not work. But when I reload the backend server, somehow it works for no reason.
Below are my codes
Frontend side
const socket = io.connect("http://127.0.0.1:3000", { cors: true }); //backend server
socket.on("connection", async (data) => { // it works
try {
console.log(data);
} catch (err) {
console.error(err.response);
}
});
socket.on("notify", async (notify) => { // it does not works while I reload backend server
try {
console.log(notify);
} catch (err) {
console.error(err.response);
}
});
Backend side
index.js
const app = express();
const PORT = process.env.PORT || 3000;
app.use(cors({ origin: "http://127.0.0.1:3060" }));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
const Socket = require("./socket");
const server = app.listen(PORT, function () {
return console.log("Backend server listening on port" + PORT);
});
Socket(server, app);
socket.js
const Socket = require("socket.io");
const axios = require("axios");
module.exports = (server, app) => {
const io = Socket(server, {
cors: {
origin: "*",
},
});
io.on("connection", (socket) => {
console.log("socket is connected");
app.post("/webhook/notify", (req, res, next) => {
try {
socket.emit("notify", req.body);
} catch (err) {
console.error(err.response);
return next(err);
}
});
socket.on("disconnect", () => {
console.log("disconnected");
});
});
};

Related

Socket.io server not runnning

i'm developing a chat app in express by socket.io and this is my code:
well the front end cannot connect to socket io but server is running and i can login
const express = require("express");
const { Server } = require("socket.io");
const helmet = require("helmet");
const cors = require("cors");
const authRouter = require("./routes/authRouter");
const { corsConfig } = require("./controllers/serverController");
const {
Authorization,
AddFriend,
Disconnect,
dm,
} = require("./controllers/socketController");
require("dotenv").config();
const app = express();
const server = require("http").createServer(app);
const io = new Server(server, {
cors: corsConfig,
});
app.use(helmet());
app.use(cors(corsConfig));
app.use(express.json());
//! Routes
app.use("/auth", authRouter);
app.get("/", (req, res) => res.send("Hi"));
io.use(Authorization);
io.on("connection", (socket) => {
console.log("socket")
socket.on("add_friend", (friendName, cb) => {
AddFriend(socket, friendName, cb);
});
socket.on("disconnect", Disconnect);
socket.on("dm", (message) => dm(socket, message));
});
server.listen(5050, () => {
console.log(app.get("env"));
});
but my server isnt running on localhost:5050 this is the error i got :
curl "http://localhost:5050/socket.io/?EIO=4&transport=polling" curl: (7) Failed to connect to localhost port 5050: Connection refused
ive tried to change config of socket server but none of those worked
i have a socketjs file which will create my config and a useEffect hook which inside that ive tried to connect to my server
frontendCode:
socket.js
import { io } from "socket.io-client";
const socket = (user) =>
new io("http://localhost:5050", {
autoConnect: false,
withCredentials: true,
auth: {
token: user.token,
},
});
export default socket;
useSocket.js:
socket.connect();
socket.on("friends", (FriendList) => {
setFriendList(FriendList);
});
socket.on("messages", (messages) => {
setMessages(messages);
});
socket.on("dm", (message) => {
setMessages((prev) => [message, ...prev]);
});
socket.on("connected", (status, username) => {
setFriendList((prev) => {
const friends = [...prev];
return friends.map((friend) => {
if (friend.username === username) {
friend.status = status;
}
return friend;
});
});
});
socket.on("connect_error", () => {
setUser({ loggedIn: false });
});
returned error from frontend:
Firefox can’t establish a connection to the server at ws://localhost:5050/socket.io/?EIO=4&transport=websocket&sid=1uKM4znamAHH8P6kAAKY.

What is difference between socket and io in socket.io backend?

I am very new to this socket programming. I got confused when to use io and socket in below code. Here, when a new user connects to the server and listens to any events then we use socket.on for that but while sending back response we use io.emit, cant we use socket.emit here? and what is the difference between them?
const express = require('express');
const app = express();
const PORT = 4000;
const http = require('http').Server(app);
const cors = require('cors');
app.use(cors());
const io = require('socket.io')(http, {
cors: {
origin: "http://localhost:3000"
}
});
let users = [];
io.on('connection', (socket) => {
console.log(`⚡: ${socket.id} user just connected!`);
socket.on('newUser', (data) => {
users.push(data);
io.emit('newUserResponse', users);
});
socket.on('message', (data) => {
console.log(data);
io.emit('messageResponse', data);
});
socket.on('disconnect', () => {
console.log('🔥: A user disconnected');
users = users.filter((user) => user.socketID !== socket.id);
io.emit('newUserResponse', users);
socket.disconnect();
});
});
app.get('/api', (req, res) => {
res.json({
message: 'Hello world',
});
});
http.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});

Socket.io messaging app not sending messages with express server

I'm building a messaging feature with socket.io and a React frontend. With a socket.io only server it is working as expected, with the following code:
Socket.io server only
const io = require("socket.io")(5000, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
const id = socket.handshake.query.id;
socket.join(id);
socket.on("send-message", ({ recipients, text }) => {
recipients.forEach((recipient) => {
const newRecipients = recipients.filter((r) => r !== recipient);
newRecipients.push(id);
socket.broadcast.to(recipient).emit("receive-message", {
recipients: newRecipients,
sender: id,
text,
});
});
});
});
I am trying to integrate with express. The server is starting with the code below but messaging is no longer working:
Express server
const express = require("express");
const socketIo = require("socket.io");
const cors = require("cors");
const PORT = process.env.PORT || 5000;
const app = express();
const http = app.listen(PORT, () =>
console.log(`🚀 Server ready at http://localhost:${PORT}`)
);
const io = socketIo(http, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST", "send-message", "receive-message"],
},
});
io.once("connection", (socket) => {
const id = socket.handshake.query.id;
socket.join(id);
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
socket.on("send-message", ({ recipients, text }) => {
recipients.forEach((recipient) => {
const newRecipients = recipients.filter((r) => r !== recipient);
newRecipients.push(id);
socket.broadcast.to(recipient).emit("receive-message", {
recipients: newRecipients,
sender: id,
text,
});
});
});
});
Running it locally for both instances in Chrome with a window and another incognito window open on localhost:3000
As described here on('connection') event on client side not work. Change it to on('connect');
// server-side
io.on("connection", (socket) => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});
// client-side
socket.on("connect", () => {
console.log(socket.id); // x8WIv7-mJelg7on_ALbx
});

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'})

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}`);
});

Resources