准备写一个Nodejs在线考试系统
准备写一个Nodejs在线考试系统
node + redis(optional) + mongodb + socket.io
- 暂且只支持选择题
- 管理页面允许添加题目及对应答案
- 自动判卷,提交后立即显示pass or fail, 同时给出答对题数
- 有注册及登录页面, 后期连LDAP直接验证
- 广播栏实时显示(在每个人的浏览器中,通过socket.io) a. 哪些人登录进来了,哪些人退出了 b. 哪些人完成了 c. 哪些人得高分,比如超过90分 d. 每15分钟提醒一次时间, 警告一下不要baidu等等
- 性能需求 (支持100个并发用户) a. 刚开始登录高峰期 b. 打开试卷第二个高峰期 c. 提交结果第三个高峰期 (比前两个略好,完成时间不一)
- 安全需求 mongodb要设置安全设置,不能让用户用客户端连上然后直接find()
4 回复
准备写一个Node.js在线考试系统
技术栈
node + redis(optional) + mongodb + [socket.io]
功能描述
-
支持选择题
- 仅支持选择题,可以使用单选按钮实现。
-
管理页面允许添加题目及对应答案
- 管理员可以通过管理页面添加题目及其正确答案。
- 示例代码:
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); } });
-
自动判卷,提交后立即显示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); } });
-
有注册及登录页面,后期连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); } });
-
广播栏实时显示(通过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 });
-
性能需求
- 支持100个并发用户。
- 在登录高峰期、打开试卷高峰期和提交结果高峰期,确保系统稳定运行。
-
安全需求
- MongoDB需要设置安全措施,防止用户通过客户端直接连接并查询数据。
- 示例配置:
mongoose.connect('mongodb://localhost:27017/examdb', { useNewUrlParser: true, useUnifiedTopology: true, auth: { user: 'yourUsername', password: 'yourPassword' } });
以上是一个初步的Node.js在线考试系统的实现方案。您可以根据具体需求进行调整和扩展。
目前已经有很多在线考试系统,大部分给人的印象不深刻。但是楼主现在做这个明显是晚人一步。建议楼主转做基于智能终端的考试平台。 另外,希望楼主 能思考一下所做应用系统的 主要用户,站在他们的立场去思考 他们想要什么。把他们的带有差异化的需求 提纯成一个简单实用,PC+Mobile的系统平台。
要实现一个Node.js在线考试系统,你可以考虑以下架构和技术选型:
- 后端逻辑:使用Node.js来处理请求、操作数据库、与Redis(可选)进行交互等。
- 数据库:MongoDB用于存储试题、用户信息和答题记录。
- 前端展示:可以使用EJS或Pug等模板引擎生成HTML页面,也可以使用React或Vue等现代前端框架构建SPA应用。
- 实时通信:利用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进行身份验证和授权。
这个简单的示例展示了如何搭建基本框架。具体实现还需要根据需求细化功能,并进行详细的错误处理和测试。