将MongoDB用于实时聊天数据库

问题描述 投票:0回答:1

我正在一个个人项目上,以提高我在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
}
node.js mongodb mongoose
1个回答
0
投票

一种简单的方法是仅使用一个模式Room模式来构造数据库。当用户在一个房间中发送消息时,将其推送到该房间的消息数组。然后,在socket.io(节点)中,发出一个套接字(带有房间ID)并发送消息,然后在客户端将用户设置为接收该房间的所有套接字。

房间架构:

{ID,讯息:[{ID,authorUsername,内容}]}
© www.soinside.com 2019 - 2024. All rights reserved.