本文 demo 基于上一篇博文(pomelo链接mysql),将暴露给客户端的 servers 逻辑部分解耦到 service 层,从而实现关注点分离。

需求:把购买物品的逻辑解耦到 service 目录。

在 Handler 中添加持久对象

在 Handler 构造函数中引入并实例化 GoodsService,挂载为 this.GoodsService:


                module.exports = function (app) {
                    return new Handler(app);
                };
                
                var Handler = function (app) {
                    this.app = app;
                
                
                    var GoodsService = require(app.getBase() + "/app/service/game/GoodsService.js");
                    this.GoodsService = new GoodsService();
                
                
                };
                var handler = Handler.prototype;
                
                

修改 gameHandler.js 中的 buyGoods 函数

将原来内联的购买逻辑委托给 this.GoodsService.buyGoods:

handler.buyGoods = function (msg, session, next) {
                    var id = msg.id;
                    var count = msg.count;
                
                    ///////////////////////////////
                
                    if (id == "100" && count == 1) {//验证购买条件        //允许购买
                
                        this.GoodsService.buyGoods(msg.id, session.uid, function (err, res) {
                
                            if (err) { // 购买失败
                                console.error("[Error]:数据库服务器错误");
                                next(null, { msg: "购买失败,服务器错误!", code: 200 });
                
                            }
                            else {//购买成功
                                next(null, { msg: "购买物品:#活血丹 成功", code: 200 });
                
                            }
                        });
                
                    } else { // 不允许购买
                        next(null, { msg: "你的金币不足,购买失败", code: 200 });
                    }
                
                
                }
                //还可以进一步解耦为
                handler.buyGoods = function (msg, session, next) {
                        this.GoodsService.buyGoods(msg.id, session.uid, next);
                }
                

新建 GoodsService.js

添加 game-server\app\service\game\GoodsService.js,封装数据库操作:

function GoodsService() {
                    console.error("[GoodsService]:new GoodsService"); // 检测不同的客户端是否会new 该脚本
                }
                
                GoodsService.prototype.buyGoods = function (id, owner, cb) {
                    var sql = " insert into `goods` (`id`, `owner`) VALUES(?, ?)";
                
                    var args = [id, owner];
                    var dbclient = pomelo.app.get('dbclient');//获取全局mysql client
                
                    console.log(dbclient);
                    dbclient.query(sql, args, function (err, res) {//执行sql语句 函数insert和query等效
                
                        cb(err, res);
                    });
                
                };
                
                module.exports = GoodsService;
                
                
                //进一步解耦 在这里 不列出

新建多个客户端连接后可以观察到:构造器只被调用了一次,说明所有客户端共享同一个服务器的 handler 实例。因此,合理利用路由来分配服务器压力尤为重要。