mongodb安装在win10下环境的问题
我的开发环境是老版本的win10,一开始安装的mongodb社区版的8.3版本,结果经常报1053错误无法启动mongod服务。查了半天结果要么改到版本6,要么升级win10,我实在不愿意改操作系统开发的时候降到版本6.反正API大体上是没变化的。
核心层做了一个nodejs队mongodb通信的封装,而DBManager是在这个核心层进一步的二次封装,用来管理MongoDB 游戏数据库
MongoDB 游戏数据库管理器 DBManager
一、作用
- 封装 MongoDB 连接、CRUD、事务、聚合统计
- 给游戏业务提供玩家、房间、对局记录三大核心数据操作
- 让上层游戏逻辑不用直接写 MongoDB 语句,直接调用方法即可
- 支持断线重连、分页、排行榜、金币转账、房间管理等游戏必备功能
二、头部引入与结构
var MongooseAsync = require("../../../core/mongoose_async.js");
var UnitTools = require("../../../core/unit_tools.js");
-
MongooseAsync:异步版 Mongoose 封装(MongoDB 官方驱动) -
UnitTools:工具类,判空、校验等class DBManager {
constructor() {
this.mongoose = new MongooseAsync(); // MongoDB 驱动实例
this.connected = false; // 连接状态
this.models = {}; // 所有数据表模型(玩家、房间、记录)
this._connect_config = null; // 连接配置缓存,用于重连
}
}
构造函数做的事:
- 初始化数据库驱动
- 标记未连接
- 准备存放所有数据表(Model)
- 缓存连接信息
三、核心模块函数
1. 连接管理(最基础)
connect () ------ 连接数据库
async connect(account, pass, ip, port, db_name) {
if (!port) port = 27017;
this._connect_config = { account, pass, ip, port, db_name };
var ok = await this.mongoose.connect(account, pass, ip, port, db_name);
if (ok) {
this.connected = true;
this.define_all_models(); // 连接成功 → 自动创建所有数据表结构
console.log("MongoDB 连接成功");
}
return ok;
}
功能:
- 传入账号、密码、IP、端口、库名
- 保存配置,方便重连
- 调用底层驱动连接
- 连接成功后自动定义所有表结构
connect_with_config()
用配置文件一键连接,游戏服务器最常用。
is_connected()
返回是否连上数据库。
2. Model 定义(表结构)
这是 MongoDB 的核心:定义每张表长什么样。
define_all_models()
一次性定义三张核心表:
- 玩家表
players - 对局记录表
game_records - 房间表
room_records
① 玩家表
javascript
define_player_model() {
var schema = {
player_id: { type: String, required: true, unique: true, index: true },
nickname: { type: String, default: "" },
gold: { type: Number, default: 0 },
diamond: { type: Number, default: 0 },
total_games:{ type: Number, default: 0 },
win_games: { type: Number, default: 0 },
is_online: { type: Boolean, default: false },
last_login: { type: Date, default: null },
};
this.models.players = this.mongoose.make_model("players", schema);
}
游戏玩家的所有数据:
- ID、昵称、头像
- 金币、钻石
- 总局数、胜局数
- 是否在线、最后登录时间
type:类型 required:必须填写 unique:唯一 index:索引(加速查询)
② 对局记录表
每打完一局,就存一条记录。 包含:房间 ID、玩家列表、赢家、回合数、开始结束时间。
③ 房间表
记录每一个游戏房间:
- 房间 ID
- 类型(普通 / VIP)
- 创建者
- 最大人数
- 玩家列表
- 状态:等待中 / 游戏中 / 已结束
3. 玩家数据操作(游戏最常用)
find_player () ------ 查玩家
async find_player(player_id) {
return await this.models.players.findOne({ player_id: player_id });
}
按 ID 查玩家,返回玩家完整数据
find_or_create_player () ------ 找不到就新建
登录逻辑必备:
- 玩家第一次登录 → 自动创建账号
- 不是第一次 → 直接返回数据
update_player () ------ 更新玩家信息
async update_player(player_id, updates) {
updates.updated_at = new Date();
return await this.models.players.findOneAndUpdate(
{ player_id: player_id },
{ $set: updates },
{ new: true }
);
}
- 自动更新时间
- 只修改传入的字段
- 返回更新后的数据
4. 金币 / 钻石操作(游戏经济系统)
add_gold() / add_diamond()
async add_gold(player_id, amount) {
return await this.models.players.findOneAndUpdate(
{ player_id: player_id },
{ $inc: { gold: amount }, $set: { updated_at: new Date() } },
{ new: true }
);
}
$inc= 自增 / 自减- 传入正数 = 加金币
- 传入负数 = 扣金币
transfer_gold () ------ 玩家之间转账(事务安全)
async transfer_gold(from_player_id, to_player_id, amount) {
var from = await this.add_gold(from_player_id, -amount);
if (!from || from.gold < 0) {
await this.add_gold(from_player_id, amount); // 回滚
return false;
}
await this.add_gold(to_player_id, amount);
return true;
}
安全转账逻辑:
- 扣发起者金币
- 如果扣完余额负数 → 回滚
- 给目标加金币
- 返回成功 / 失败
这是游戏经济系统必须有的安全机制。
5. 排行榜 / 统计
async get_rank_list(sort_field, limit) {
return await this.models.players.find({})
.sort({ [sort_field]: -1 }) // 降序
.limit(limit)
.select("player_id nickname " + sort_field);
}
- 按金币 / 胜场 / 积分排序
- 取前 100 名
- 只返回需要的字段(轻量化)
6. 对局记录(历史战绩)
save_game_record()
打完一局 → 保存战绩
get_player_game_history()
玩家查看历史战绩:
- 分页
- 按时间倒序
- 返回总条数 + 列表
7. 房间管理(匹配 / 开房系统)
create_room () ------ 创建房间
player_join_room () ------ 玩家加入
async player_join_room(room_id, player_id) {
var room = await this.find_room(room_id);
if (room.player_ids.length >= room.max_players) return null; // 满员
if (room.player_ids.includes(player_id)) return room; // 已在房间
return await this.models.room_records.findOneAndUpdate(
{ room_id: room_id },
{ $push: { player_ids: player_id } } // 加入数组
);
}
加入房间逻辑:
- 满员不能进
- 已在房间不能重复进
- 成功 → 把玩家 ID push 进房间玩家列表
player_leave_room () ------ 离开
$pull 从数组删除元素
update_room_status () ------ 更新房间状态
waiting → playing → finished
8. 通用 CRUD(给外部灵活调用)
async find_with_pagination(model_name, filter, options) { ... }
async count() { ... }
async insert() { ... }
async update_one() { ... }
async delete_many() { ... }
通用分页查询、计数、增删改查 让业务层不用写 MongoDB 语法,直接调用。
9. 数据统计(后台管理系统用)
aggregate_daily_game_count()
按天统计每日对局量
aggregate_player_stats()
统计:
- 总玩家数
- 全服总金币
用于数据看板、GM 后台。
10. 断开连接
async disconnect() {
await this.mongoose.db.disconnect();
this.connected = false;
}
四、代码在游戏里怎么用
// 1. 创建数据库实例
var db = new DBManager();
// 2. 连接数据库
await db.connect_with_config(config.db);
// 3. 玩家登录
var player = await db.find_or_create_player("player_1001");
// 4. 加金币
await db.add_gold("player_1001", 1000);
// 5. 创建房间
await db.create_room("room_666", { creator_id:"player_1001" });
// 6. 玩家加入房间
await db.player_join_room("room_666", "player_1002");
// 7. 打完一局,保存战绩
await db.save_game_record(record);
// 8. 查询历史
var history = await db.get_player_game_history("player_1001");
伍、总结
- DBManager = 游戏服务器的数据库管家
- 封装了玩家、房间、对局记录三大模块
- 提供增删改查、经济系统、房间逻辑、数据统计全套功能