实时聊天数据库"/>
将MongoDB用于实时聊天数据库
我正在一个个人项目上,以提高我在Node.js,Express,Socket.io和MongoDB方面的技能和经验。我似乎在制定数据库应如何用于此类应用程序方面遇到了障碍。我的应用程序允许用户输入用户名并选择房间标题。此后,他们将被加载到房间中,其他人可以加入该房间并实时聊天。我要保留数据,在断开连接时将其保存在每个房间,并在连接时重新填充。每个房间都有与之关联的名称以及消息本身。每条消息都有一个发件人名称,时间戳和文本/内容。但是,在实际构建模型以及如何组织集合方面,我感到困惑。谁能帮助我或让我走上正确的道路?
server.js(后端)
require('dotenv').config();
const path = require('path');
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const mongoose = require('mongoose');
const formatMessage = require('./utils/messages');
const {
userJoin,
getCurrentUser,
userLeave,
getRoomUsers
} = 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')));
const botName = 'ChatCord Bot';
const messages = [];
//Database connection
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
});
const connection = mongoose.connection;
connection.once('open', () => {
console.log("MongoDB database connection established successfully");
})
// Run when client connects
io.on('connection', socket => {
socket.on('joinRoom', ({
username,
room
}) => {
const user = userJoin(socket.id, username, room);
socket.join(user.room);
// Welcome current user
socket.emit('message', formatMessage(botName, 'Welcome to ChatCord!'));
//Load messages for room from database
socket.broadcast.to(user.room).emit(
'message', formatMessage()
)
// Broadcast when a user connects
socket.broadcast
.to(user.room)
.emit(
'message',
formatMessage(botName, `${user.username} has joined the chat`)
);
// Send users and room info
io.to(user.room).emit('roomUsers', {
room: user.room,
users: getRoomUsers(user.room)
});
});
// Listen for chatMessage
socket.on('chatMessage', msg => {
const user = getCurrentUser(socket.id);
io.to(user.room).emit('message', formatMessage(user.username, msg));
});
// Runs when client disconnects
socket.on('disconnect', () => {
const user = userLeave(socket.id);
if (user) {
io.to(user.room).emit(
'message',
formatMessage(botName, `${user.username} has left the chat`)
);
// Send users and room info
io.to(user.room).emit('roomUsers', {
room: user.room,
users: getRoomUsers(user.room)
});
}
//Save messages for room to database
});
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
main.js(frontend)
const chatForm = document.getElementById('chat-form');
const chatMessages = document.querySelector('.chat-messages');
const roomName = document.getElementById('room-name');
const userList = document.getElementById('users');
//Get username and room from URL
const {username, room } = Qs.parse(location.search, {
ignoreQueryPrefix: true
});
console.log(username, room);
const socket = io();
//Join chatroom
socket.emit('joinRoom', {username, room});
//Get room and users
socket.on('roomUsers', ({ room, users }) => {
outputRoomName(room);
outputUsers(users);
})
socket.on('message', message => {
outputMessage(message);
//Scroll down on new message
chatMessages.scrollTop = chatMessages.scrollHeight;
});
//Message submit
chatForm.addEventListener('submit', (e) => {
e.preventDefault();
//Get message text
const msg = e.target.elements.msg.value;
//Emit message to server
socket.emit('chatMessage',msg);
//Clear input
e.target.elements.msg.value = '';
e.target.elements.msg.focus();
});
//Output message to DOM
function outputMessage(message) {
const div = document.createElement('div');
div.classList.add('message');
div.innerHTML = `<p class="meta">${message.username} <span>${message.time}</span></p>
<p class="text">
${message.text}
</p>`;
document.querySelector('.chat-messages').appendChild(div);
}
//Add room name to DOM
function outputRoomName(room) {
roomName.innerText = room;
}
//Add users to DOM
function outputUsers(users) {
userList.innerHTML = `${users.map(user => `<li>${user.username}</li>`).join('')}`;
}
room.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const roomSchema = new Schema({
id: mongoose.ObjectId,
messages: [
{
id: mongoose.ObjectId,
authorUsername: String,
time: Date,
content: String
}
]
});
const Room = mongoose.model("Room", roomSchema);
module.exports = Room;
users.js
const users = [];
//Join user to chat
function userJoin(id, username, room) {
const user = {id, username, room};
users.push(user);
return user;
}
//Get current user
function getCurrentUser(id) {
return users.find(user => user.id === id);
}
//User leaves chat
function userLeave(id) {
const index = users.findIndex(user => user.id === id);
if(index !== -1) {
return users.splice(index, 1)[0];
}
}
//Get room users
function getRoomUsers(room) {
return users.filter(user => user.room === room);
}
module.exports = {
userJoin,
getCurrentUser,
userLeave,
getRoomUsers
}
回答如下:一种简单的方法是仅使用一个模式Room
模式来构造数据库。当用户在一个房间中发送消息时,将其推送到该房间的消息数组。然后,在socket.io(节点)中,发出一个套接字(带有房间ID)并发送消息,然后在客户端将用户设置为接收该房间的所有套接字。
房间架构:
{ID,讯息:[{ID,authorUsername,内容}]}
更多推荐
将MongoDB用于实时聊天数据库
发布评论