我目前正在使用 Socket.IO 和 React 创建聊天,但无法连接到我的服务器,因为连接被拒绝。我尝试在 CORS ORIGIN 中使用不同的 IP(并使用 ['*']),尝试使用
newSocket = io('localhost:4444');
,尝试使用 newSocket = io('my domain with reverse proxy to port 4444');
,唯一有效的方法是使用我的虚拟机的数字 ip newSocket = io('195.XXX.XX4:4444');
。
接下来我可以尝试什么?
我的前端托管在端口 3000 上,套接字托管在 4444 上。
React-前端:
let newSocket;
try {
newSocket = io.connect('http://localhost:4444');
} catch (e) {
console.log(e);
window.location.reload();
}
setSocket(newSocket);
return () => {
newSocket.disconnect();
};`
Socket.IO 代码(顺便说一句,注释在 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}`);
});
为什么使用 io.connect(...) ? 你能把你的前端导入吗? 代码有效吗?
根据您的代码,我可以向您推荐以下步骤:
尝试使用来自socket.io-client的io
import {io} from "socket.io-client";
//other code
let newSocket = io('http://localhost:4444');
//or let newSocket = io('195.XXX.XX4:4444');
//other code
您错过了socket.io服务器:
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,
});
如果收到allow-origin错误,请将其添加到cors的allowedHeaders中:
'Access-Control-Allow-Origin', '*'
确保您没有在端口 3000 上启动。
const port = process.env.PORT || 3003;
让我知道它是否有效。如果没有,请为我的问题提供更多信息。