准备写一个Nodejs在线考试系统

准备写一个Nodejs在线考试系统

node + redis(optional) + mongodb + socket.io

  1. 暂且只支持选择题
  2. 管理页面允许添加题目及对应答案
  3. 自动判卷,提交后立即显示pass or fail, 同时给出答对题数
  4. 有注册及登录页面, 后期连LDAP直接验证
  5. 广播栏实时显示(在每个人的浏览器中,通过socket.io) a. 哪些人登录进来了,哪些人退出了 b. 哪些人完成了 c. 哪些人得高分,比如超过90分 d. 每15分钟提醒一次时间, 警告一下不要baidu等等
  6. 性能需求 (支持100个并发用户) a. 刚开始登录高峰期 b. 打开试卷第二个高峰期 c. 提交结果第三个高峰期 (比前两个略好,完成时间不一)
  7. 安全需求 mongodb要设置安全设置,不能让用户用客户端连上然后直接find()

4 回复

准备写一个Node.js在线考试系统

技术栈

node + redis(optional) + mongodb + [socket.io]

功能描述

  1. 支持选择题

    • 仅支持选择题,可以使用单选按钮实现。
  2. 管理页面允许添加题目及对应答案

    • 管理员可以通过管理页面添加题目及其正确答案。
    • 示例代码:
      const express = require('express');
      const mongoose = require('mongoose');
      
      const app = express();
      const Question = mongoose.model('Question', new mongoose.Schema({
        question: String,
        options: [String],
        answer: String
      }));
      
      app.post('/add-question', async (req, res) => {
        try {
          const { question, options, answer } = req.body;
          const newQuestion = new Question({ question, options, answer });
          await newQuestion.save();
          res.send("Question added successfully!");
        } catch (err) {
          res.status(500).send(err.message);
        }
      });
      
  3. 自动判卷,提交后立即显示pass or fail, 同时给出答对题数

    • 学生提交答案后,系统会自动判卷并显示成绩。
    • 示例代码:
      app.post('/submit-exam', async (req, res) => {
        try {
          const { answers } = req.body;
          const questions = await Question.find({});
          let correctCount = 0;
      
          questions.forEach(question => {
            if (answers[question._id] === question.answer) {
              correctCount++;
            }
          });
      
          const pass = correctCount / questions.length >= 0.7; // 70% as passing criteria
          res.send(`You scored ${correctCount} out of ${questions.length}. ${pass ? 'Pass!' : 'Fail.'}`);
        } catch (err) {
          res.status(500).send(err.message);
        }
      });
      
  4. 有注册及登录页面,后期连LDAP直接验证

    • 用户可以注册和登录,并且后期计划与LDAP集成。
    • 示例代码:
      const bcrypt = require('bcryptjs');
      const User = mongoose.model('User', new mongoose.Schema({
        username: String,
        password: String
      }));
      
      app.post('/register', async (req, res) => {
        try {
          const { username, password } = req.body;
          const hashedPassword = await bcrypt.hash(password, 10);
          const newUser = new User({ username, password: hashedPassword });
          await newUser.save();
          res.send("User registered successfully!");
        } catch (err) {
          res.status(500).send(err.message);
        }
      });
      
      app.post('/login', async (req, res) => {
        try {
          const { username, password } = req.body;
          const user = await User.findOne({ username });
          if (!user || !(await bcrypt.compare(password, user.password))) {
            return res.status(400).send('Invalid credentials.');
          }
          res.send("Login successful!");
        } catch (err) {
          res.status(500).send(err.message);
        }
      });
      
  5. 广播栏实时显示(通过socket.io

    • 实时广播用户登录状态、完成情况和成绩等信息。
    • 示例代码:
      const io = require('socket.io')(server);
      
      io.on('connection', socket => {
        socket.on('login', () => {
          io.emit('user-login', socket.id);
        });
      
        socket.on('logout', () => {
          io.emit('user-logout', socket.id);
        });
      
        socket.on('complete', () => {
          io.emit('user-complete', socket.id);
        });
      
        setInterval(() => {
          io.emit('time-warning', `Time left: ${Math.floor(Date.now() / 1000) % 900}s`);
        }, 900000); // every 15 minutes
      });
      
  6. 性能需求

    • 支持100个并发用户。
    • 在登录高峰期、打开试卷高峰期和提交结果高峰期,确保系统稳定运行。
  7. 安全需求

    • MongoDB需要设置安全措施,防止用户通过客户端直接连接并查询数据。
    • 示例配置:
      mongoose.connect('mongodb://localhost:27017/examdb', {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        auth: {
          user: 'yourUsername',
          password: 'yourPassword'
        }
      });
      

以上是一个初步的Node.js在线考试系统的实现方案。您可以根据具体需求进行调整和扩展。


去年做了个类似的。

目前已经有很多在线考试系统,大部分给人的印象不深刻。但是楼主现在做这个明显是晚人一步。建议楼主转做基于智能终端的考试平台。 另外,希望楼主 能思考一下所做应用系统的 主要用户,站在他们的立场去思考 他们想要什么。把他们的带有差异化的需求 提纯成一个简单实用,PC+Mobile的系统平台。

要实现一个Node.js在线考试系统,你可以考虑以下架构和技术选型:

  1. 后端逻辑:使用Node.js来处理请求、操作数据库、与Redis(可选)进行交互等。
  2. 数据库:MongoDB用于存储试题、用户信息和答题记录。
  3. 前端展示:可以使用EJS或Pug等模板引擎生成HTML页面,也可以使用React或Vue等现代前端框架构建SPA应用。
  4. 实时通信:利用Socket.IO进行实时通信,例如广播用户状态变化。

示例代码

安装依赖

npm install express socket.io mongoose body-parser ejs

文件结构

project/
├── app.js
├── models/
│   └── Question.js
├── routes/
│   └── examRoutes.js
├── views/
│   └── index.ejs
└── public/
    └── js/
        └── client.js

app.js

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// MongoDB连接
mongoose.connect('mongodb://localhost:27017/exam', { useNewUrlParser: true, useUnifiedTopology: true });

// 中间件
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static('public'));

// 引入路由
require('./routes/examRoutes')(app, io);

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

models/Question.js

const mongoose = require('mongoose');

const questionSchema = new mongoose.Schema({
    questionText: String,
    options: [String],
    correctOption: Number,
    addedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});

module.exports = mongoose.model('Question', questionSchema);

routes/examRoutes.js

module.exports = function(app, io) {
    const Question = require('../models/Question');

    app.get('/', (req, res) => {
        res.render('index');
    });

    // 添加更多API接口...
};

views/index.ejs

<!DOCTYPE html>
<html>
<head>
    <title>Online Exam System</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="/js/client.js"></script>
</head>
<body>
    <h1>Welcome to Online Exam</h1>
    <!-- 你的前端表单 -->
</body>
</html>

public/js/client.js

const socket = io();

socket.on('connect', () => {
    console.log('Connected to server');
});

socket.on('disconnect', () => {
    console.log('Disconnected from server');
});

// 其他事件监听...

性能和安全

  • 使用PM2或类似工具进行负载均衡和集群管理,以提高并发处理能力。
  • 确保MongoDB的安全配置,如使用认证机制和限制不必要的访问。
  • 对敏感操作使用JWT或OAuth进行身份验证和授权。

这个简单的示例展示了如何搭建基本框架。具体实现还需要根据需求细化功能,并进行详细的错误处理和测试。

回到顶部