I'm currently using Socket.IO and React to create a chat, but I can't connect to my server because the connection is being refused. I tried using different IP in CORS ORIGIN (and using ['*']), tried using newSocket = io('localhost:4444');
, tried using newSocket = io('my domain with reverse proxy to port 4444');
, the only way it works is using the numerical ip of my vm newSocket = io('195.XXX.XX4:4444');
.
What can I try next?
My frontend is hosted in port 3000, and the socket in 4444.
React-frontend:
let newSocket;
try {
newSocket = io.connect('http://localhost:4444');
} catch (e) {
console.log(e);
window.location.reload();
}
setSocket(newSocket);
return () => {
newSocket.disconnect();
};`
Socket.IO code (btw the comments are in pt-br):
const express = require('express');
const mongoose = require('mongoose');
const http = require('http');
const socketIo = require("socket.io");
const Chat = require('./models/Chat.js');
const dotenv = require("dotenv");
const cors = require('cors'); // Importe a biblioteca CORS
const app = express();
app.use((req, res, next) => {
res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' https://www.googletagmanager.com https://cdnjs.cloudflare.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com;");
next();
});
dotenv.config();
const port = process.env.PORT || 3000;
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: ['http://localhost:3000'],
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
},
debug: true,
});
// Use a biblioteca CORS como middleware
app.use(cors({
origin: ['http://localhost:3000'],
methods: ['GET', 'POST', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
}));
mongoose.connect(`mongodb+srv://${process.env.DB_USERNAME}:${process.env.DB_PASSWORD}@yc-cluster.bn5qm0z.mongodb.net/socketio`, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log('Connected to MongoDB Atlas');
})
.catch((err) => {
console.error('Error connecting to MongoDB Atlas:', err);
});
const chatRoutes = require('./routes/chatRoutes');
app.use(express.json());
app.use('/api', chatRoutes);
// SOCKET DE CONEXÃO
io.on('connection', (socket) => {
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
console.log('User connected in socket');
socket.on('join chat', (id_do_clube) => {
const { id_club } = id_do_clube;
const chatRoom = 'chat_' + id_club;
socket.join(chatRoom);
console.log('User connected in chat room: ' + 'chat_' + id_club);
socket.on('disconnect', () => {
console.log('User disconnected');
});
// SOCKET DE ENVIO DE MENSAGENS
socket.on('chat message', async (message) => {
// Salvar a mensagem no banco de dados
const chat = new Chat({
sender: message.sender,
message: message.message,
id_club: message.id_club,
id_user: message.id_user,
sender: message.sender,
sender_image: message.sender_image,
announcement: message.announcement,
type: message.type,
role: message.role,
});
try {
const newChat = await chat.save();
socket.emit('chat message', newChat);
io.to(chatRoom).emit('chat message', newChat);
socket.emit('chat message response', "Mensagem enviada com sucesso");
} catch (err) {
console.error('Error saving chat message:', err);
}
});
socket.on('get old messages', async (id_club) => {
try {
const oldChats = await Chat.find({ id_club }).sort({ timestamp: 'asc' });
socket.emit('old messages', oldChats);
} catch (err) {
console.error('Error retrieving old messages:', err);
}
});
// SOCKET DE EDIÇÃO DE MENSAGENS
socket.on('edit message', async (editedMessage) => {
try {
const { messageId, newMessage, id_user } = editedMessage;
const chat = await Chat.findById(messageId);
if (!chat) {
console.error('Mensagem não encontrada');
}
if (parseInt(chat.id_user) !== parseInt(id_user)) {
console.error('Usuário sem permissão de editar a mensagem');
}
const updatedChat = await Chat.findByIdAndUpdate(
messageId,
{ message: newMessage, edited: true },
{ new: true }
);
// Emitir evento para informar que deu certo para o cliente
socket.emit('message edited response', "Mensagem editada com sucesso");
// Obter as mensagens atualizadas para o chat específico
const id_club = updatedChat.id_club;
const updatedMessages = await Chat.find({ id_club }).sort({ timestamp: 'asc' });
// Emitir evento para atualizar a lista de mensagens para o chat específico
io.to(chatRoom).emit('updated message list', { id_club, messages: updatedMessages });
} catch (err) {
console.error('Error editing message:', err);
}
});
// SOCKET DE DELEÇÃO DE MENSAGENS
socket.on('delete message', async (infos) => {
try {
const { messageId, id_user } = infos;
const chat = await Chat.findById(messageId);
if (!chat) {
console.error('Mensagem não encontrada');
return;
}
// Verificar se o usuário que está tentando deletar a mensagem é o mesmo que a enviou
if (parseInt(chat.id_user) !== parseInt(id_user)) {
console.error('Usuário sem permissão de deletar a mensagem');
return;
}
// Salvar a mensagem antiga antes de excluí-la
const oldMessage = chat.message;
// Atualizar a mensagem para "Esta mensagem foi excluída" e marcar como deletada
chat.message = "Esta mensagem foi excluída";
chat.deleted = true;
chat.oldMessage = oldMessage; // Salvar a mensagem antiga em um campo separado, se necessário
// Salvar as alterações no documento
await chat.save();
// Emitir evento para informar que deu certo a atualização da mensagem para o cliente
socket.emit('message deleted response', "Mensagem excluída com sucesso");
// Obter as mensagens atualizadas para o chat específico
const id_club = chat.id_club;
const updatedMessages = await Chat.find({ id_club }).sort({ timestamp: 'asc' });
// Emitir evento para atualizar a lista de mensagens para o chat específico
io.to(chatRoom).emit('updated message list', { id_club, messages: updatedMessages });
} catch (err) {
console.error('Error deleting message:', err);
}
});
});
});
server.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Why you use io.connect(...) ? Can you put your frontend import? Is the code in a useeffect?
From your code I can recommend you these steps:
Try to use io from socket.io-client
import {io} from "socket.io-client";
//other code
let newSocket = io('http://localhost:4444');
//or let newSocket = io('195.XXX.XX4:4444');
//other code
You missed the socket.io Server:
const { Server } = require("socket.io");
//other import and code
const io = new Server(server, {
cors: {
origin: ['http://localhost:3000'],
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
},
debug: true,
});
If you receive allow-origin error, add this to allowedHeaders of cors:
allowedHeaders: ['Content-Type', 'Authorization','Access-Control-Allow-Origin', '*']
Make sure you are not starting on port 3000.
const port = process.env.PORT || 3000;
Let me know if it works. If not, give me more info for my questions.