-
Notifications
You must be signed in to change notification settings - Fork 160
Guide
Quick-pomelo is based on pomelo, you should first understand the pomelo framework.
Quick-pomelo use memdb to manage data model and data access, so understanding memdb is required.

IMPORTENT
- Quick-pomelo based on memdb, please first read memdb architecture carefully
- Read Pomelo framework overview if you don't familiar with pomelo
Define all your data models here.
Model is just mdbgoose schema, you should write models as below.
// app/models/player.js
// app is pomelo instance passed by framework
module.exports = function(app){
// get mdbgoose instance
var mdbgoose = app.memdb.goose;
// define mdbgoose model
var PlayerSchema = new mdbgoose.Schema({
_id : {type : String},
areaId : {type : String},
teamId : {type : String},
connectorId : {type : String},
name : {type : String},
}, {collection : 'players'});
mdbgoose.model('Player', PlayerSchema);
};You can access models by
var Player = app.models.Player;Note that database index should be defined inside .memdb.js
Put all controllers here.
Write all your business logic in controller as below
// app/controllers/player.js
// app is passed from framework
var Controller = function(app){
this.app = app;
};
// define controller methods
Controller.prototype.createPlayerAsync = function(opts){
var player = new this.app.models.Player(opts);
yield player.saveAsync();
};
// export controller
module.exports = function(app){
return new Controller(app);
};You can access controllers by
var playerController = app.controllers.player;For each type of server, write a route in app/routes directory.
A route function accepts a request info (as session, method, msgs), and output a routing key. Routing key is string, requests with the same routing key will be always forwarded to the same backend server.
Writing route properly is crucial for performance, please read performance optimize.
Please write routes as below
// app/routes/player.js
// router for serverType 'player'
module.exports = {
// Route for handler
handler : function(session, method, msg){
// Return a string routing key
return session.uid || msg.playerId;
},
// Route for remote
remote : function(routeParam, method, args){
// Return a string routing key
return routeParam;
}
};If no routes provided, the backend server forwarded is undetermined.
Memdb client config
Every pomelo server is a memdb client, which use pomelo server id (by app.getServerId()) as the routing shardId for memdb transaction. Although not required, there is 1-1 relationship between a pomelo server and a memdb shard.
{
"shards" : {
// pomelo serverId : memdb shard host and port
"area-server-1" : {
"host" : "127.0.0.1",
"port" : 31017
},
"area-server-2" : {
"host" : "127.0.0.1",
"port" : 31018
},
// ......
}
}Memdb server config, please refer to .memdb.js wiki.
Specify the config file by --conf=[path to .memdb.js] when you operate memdb
Database index definition, this is included by .memdb.js
Main script, some extra code should be added to load quick-pomelo components.
This is the minimum setup, you can start with the template/app.js
var quick = require('quick-pomelo');
//...
app.configure('all', function(){
//...
// Configure memdb client
app.loadConfigBaseApp('memdbConfig', 'memdb.json');
// Load components
app.load(quick.components.memdb);
app.load(quick.components.controllers);
app.load(quick.components.routes);
// Configure filter
app.filter(quick.filters.transaction(app));
//...
});We have implemented some useful built-in controllers, you can leverage them
Here is how to make built-in controllers available in your code, we assume you want to use build-in 'push' controller
- create push.js in app/models, add following code
module.exports = require('quick-pomelo').models.push;- create push.js in app/controllers, add following code
module.exports = require('quick-pomelo').controllers.push;- Get controller instance
var pushController = app.controllers.push;A powerful push service, you can use push controller to implement chat, notification in your game, features:
- Channel subscribe control
- Message history persistent
- Offline message
Some time we need to delay execute or repeat in an interval. Timer component is useful which put every callback inside one transaction. Do not access memdb in native setTimeout/setInterval callback.
Usage
// Load the timer component
app.load(quick.components.timer);
var timeout = app.timer.setTimeout(function(){
// this is executed inside a single transaction
}, 1000);
clearTimeout(timeout);
var interval = app.timer.setInterval(fn, 1000);
clearInterval(interval);
// You can also specify an id for the timer as below
app.timer.setInterval(fn, 1000, id);
app.timer.clear(id);There are app events fired when transaction finish. You can use these event to commit/rollback changes to external resources (not in memdb).
app.on('transactionSuccess', function(){
// commit changes
});
app.on('transactionFail', function(){
// rollback changes
});Although mongoose is powerful, it has performance penalty. You can directly use raw memdb API if performance is an issue.
// Get the autoConnection object for mdbgoose
var autoconn = app.memdb.goose.autoconn;
var player = yield autoconn.collection('player').find({_id : 1});