https://github.com/NetEase/pomelo/wiki/Home-in-Chinese
所以在pomelo中我们发起rpc调用都是如下形式:
this.app.rpc.yourServerType.yourServerTypeRemote.method()

monogoose 下的几个名词解释

1.
Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力
Model : 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对
Entity : 由Model创建的实体,他的操作也会影响数据库

Schema、Model、Entity的关系请牢记,Schema生成Model,Model创造Entity,Model和Entity都可对数据库操作造成影响,但Model比Entity更具操作性。


2.在项目只能够创建一个数据库连接,如下:
var mongoose = require('mongoose'); //引用mongoose模块
var db = mongoose.createConnection('localhost','test'); //创建一个数据库连接

3.打开本机localhost的test数据库时,我们可以监测是否有异常
db.on('error',console.error.bind(console,'连接错误:'));
db.once('open',function(){
//一次打开记录
});
4.定义一个Schema
var PersonSchema = new mongoose.Schema({
name:String //定义一个属性name,类型为String
vid: {type: String, default: ""},
uid: {type: String, default: ""},
password: {type: String, default: ""},
loginMode: {type: String, default: ""},
equipmentID: {type: String, default: ""},
});
5.将该Schema发布为Model

var PersonModel = db.model('Person',PersonSchema);
//如果该Model已经发布,则可以直接通过名字索引到,如下:
//var PersonModel = db.model('Person');
//如果没有发布,上一段代码将会异常
6.用Model创建Entity

var personEntity = new PersonModel({name:'Krouky'});
//打印这个实体的名字看看
console.log(personEntity.name); //Krouky
7.我们甚至可以为此Schema创建方法

//为Schema模型追加speak方法
PersonSchema.methods.speak = function(){
console.log('我的名字叫'+this.name);
}
var PersonModel = db.model('Person',PersonSchema);
var personEntity = new PersonModel({name:'Krouky'});
personEntity.speak();//我的名字叫Krouky
8.Entity是具有具体的数据库操作CRUD的

personEntity.save(); //执行完成后,数据库就有该数据了
9.如果要执行查询,需要依赖Model,当然Entity也是可以做到的

PersonModel.find(function(err,persons){
//查询到的所有person
});
//只查询vid,uid字段,当为1的时候表示显示
db.getCollection('user').find({'vid':'8741ae3c8'},{"vid":1,"uid":1})


//promise的例子
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, time);
})
};
var start = async function () {
// 在这里使用起来就像同步代码那样直观
console.log('start');
await sleep(3000);
console.log('end');
};
start();
控制台先输出start,稍等3秒后,输出了end。
async 表示这是一个async函数,await只能用在这个函数里面。
await 表示在这里等待promise返回结果了,再继续执行。
await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了…)
return new Promise(function (resolve, reject) {
client.setnx(tableid, type, function (error, res) {
if (!error && res === 1) {
//zuoxia
logger.info("res= ", res);
client.expireat(tableid, parseInt((+new Date) / 1000) + 1);
return resolve({ result: true });
} else {
logger.info("err= ", error);
resolve({ result: false });
}
})
});

var channel = this.channelService.getChannel(name, flag);
channelService和之前的sessionService类似,用与管理channel。当flag为true且名为name的channel不存在,则会创建channel,否则返回名为name的channel

http://127.0.0.1:5790/index.html?openid=myaccount2&fid=1500056&game=SutraNiuniu


var a = 1;
var obj = {
b: 2
};
var fn = function () {};
fn.c = 3;

function test(x, y, z) {
x = 4;
y.b = 5;
z.c = 6;
return z;
}
test(a, obj, fn);
alert(a + obj.b + fn.c);
答案:12

首先test传递进去的实参中,a是基本类型(,复制了一份值),obj是object(指向地址,你动我也动),fn也当然不是基本类型啦。在执行test的时候,x被赋值为4(跟a没关系,各玩各的,a仍然为1),y的b被赋值为5,那

obj的b也变为5,z的c变为6,那fn的c当然也会是6. 所以alert的结果应该是1+5+6 =12. (其实test不返回z也一样,z仍然改变的)。

number,string类型都是基本类型,而基本类型存放在栈区,访问时按值访问,赋值是按照普通方式赋值;
对象和数组是通过引用来赋值的,所以改变a的同时b也会跟着改变。

var table = _.find(this.tables, { id: tableId });//从tables中查找到id:tableId的table
var pos = _.findIndex(this.lookers, (u) => (u.id == user.id));//根据条件找到索引

COUNT=5;
proto.randCard = function (user, lastCards) {
var count = Math.floor(lastCards.length / COUNT);
var start = _.random(0, count - 1) * COUNT;
var cards = lastCards.slice(start, start + COUNT);
return cards;
};

1<<1
1<<2
1<<3
这种操作都是根据操作符左边的对象为操作对象进行操作的,
上边的意思是让左边的1左移1位10,左移2位100,左移3位1000。

arr.splice(0,2);//参数1删除元素的位子,参数2删除元素的数量,参数3以后,添加元素.
for (let i = 0; i < COUNT - 1; ++i) {
for (let j = i + 1; j < COUNT; ++j) {
if ((this.getLogic(cards[i]) + this.getLogic(cards[j])) % 10 == mod) {
let ti = cards[i], tj = cards[j];
cards.splice(j, 1); cards.splice(i, 1);
cards.push(ti, tj); return handCard;
}
}
}

如果一个数组中要连续多次使用splice()删除元素,一定要先删除后边的元素,再删除前边的元素。
因为第二个以后splice(),都是在前边使用splice()之后,重新生成数组的基础上使用的,举个例子:

先删除第一个元素,再删除第五个元素
var arr=[1,2,3,4,5];
arr.splice(0,1);//log(arr) [2,3,4,5];
arr.splice(4,1);//log(arr) [2,3,4,5];

先删除第五个元素,再删除第一个元素
arr.splice(4,1);//log(arr) [1,2,3,4];
arr.splice(4,1);//log(arr) [2,3,4];

var szTable = "user";
var player = await this.app.mongooseIn.m_mapModel[szTable].findOne({uid:user.id}, 'diamond cost');
if (!player) {
logger.info('没查到当前玩家 user.chairId= %d ', user.chairId);
return { code: C.FAILD, msg: C.PLAYER_NOT_FOUND };
}

var szTable = "user";
var update = { $set: { diamond: player.diamond, cost: player.cost}};
//更新 db
var user=await app.mongooseIn.m_mapModel[szTable].update({ uid: user.id }, update);
if(user){
console.log("更新用户信息user:",user);
}

node.js中的定时器:
this.ServerStartGame = setTimeout(() => this.compelUserReady(), 3000);

var pos = _.findIndex(this.lookers, (u) => (u.id == user.id));
if (pos != -1) {
return { code: C.FAILD, msg: C.TABLE_HAS_ALREADY };
}

js中截取字符串的长度:
var str="abcdefg@mnopqrst";
console.log(str.length);
//var a=str.indexOf('@');//找到字符的位置
var a=str.substr(0,str.indexOf('@'));
var b=str.substr(str.indexOf('@')+1,str.length);
console.log(a);
console.log(b);

//用slice() 和concat()可以实现数组的深拷贝
var testA=[3,2,5,6,4,4,5,6];
var testB=testA.concat();
testA.push(7);
console.log(testA);
console.log(testB);

 

var cards=[3,2,9,6,8,4,5];
var cardTemp=_.clone(cards);
var cardTempEx=_.clone(cards);
var cardTh=_.clone(cards);
var vps = _.sortBy(_.map(cards, function (n) { //按数组cards升序排序,生成一个新的数组,cards不变
console.log(n);
return n;
}));
console.log("cards:",cards); //cards: [ 3, 2, 9, 6, 8, 4, 5 ]
console.log("vps:",vps); //vps: [ 2, 3, 4, 5, 6, 8, 9 ]
console.log("cardTemp:",cardTemp);//cardTemp: [ 3, 2, 9, 6, 8, 4, 5 ]
console.log("..................................");

var c=_.difference(_.values(cardTemp),[2]);//删除数组cardTemp中第二个元素,产生一个新的数组,cardTemp不变
console.log("c:",c); //c: [ 3, 9, 6, 8, 4, 5 ]
console.log("cardTemp:",cardTemp); //cardTemp: [ 3, 2, 9, 6, 8, 4, 5 ]

var mapkey=_.mapKeys(cardTempEx, function (value, key) {
return key;
//if (value === 3) return key; delete d[key];
});
console.log("mapkey:",mapkey); //mapkey: { '0': 3, '1': 2, '2': 9, '3': 6, '4': 8, '5': 4, '6': 5 }

var keys = _.map(_.keys(mapkey), function (n) { return Number(n) });
console.log("keys:",keys); // keys: [ 0, 1, 2, 3, 4, 5, 6 ]

var values=_.map(_.values(mapkey),function(n){return Number(n)})
console.log("values:",values); //values: [ 3, 2, 9, 6, 8, 4, 5 ]

console.log("mapkey:",mapkey); //mapkey: { '0': 3, '1': 2, '2': 9, '3': 6, '4': 8, '5': 4, '6': 5 }

var bv = _.values(mapkey);
console.log("bv:",bv); //bv: [ 3, 2, 9, 6, 8, 4, 5 ]
console.log("mapkey:",mapkey);

//var maxCard=_.maxBy(mapkey,);
var indexTest=[4,5,6,7];
var index=_.findIndex(indexTest,function(n){return Number(n)==7;});
console.log("index:",index); //index: 3
console.log("indexTest:",indexTest);//indexTest: [ 4, 5, 6, 7 ]

var boolArrTest=[3,4,5,6,7];
var boolArr = _.map(boolArrTest, function (n, i, a) {
console.log("n:",n,"i:",i,"a:",a);
if (a.length === (i + 1)) return true;
return (n + 1) === a[i + 1];
});
//n: 3 i: 0 a: [ 3, 4, 5, 6, 7 ]
//n: 4 i: 1 a: [ 3, 4, 5, 6, 7 ]
//n: 5 i: 2 a: [ 3, 4, 5, 6, 7 ]
//n: 6 i: 3 a: [ 3, 4, 5, 6, 7 ]
//n: 7 i: 4 a: [ 3, 4, 5, 6, 7 ]
console.log("boolArr:",boolArr);//boolArr: [ true, true, true, true, true ]

 

 

10:03:59
罗吉飞 2018/7/5 10:03:59
mongod.exe --dbpath c:\MongoDB\data --directoryperdb --logpath c:\MongoDB\log\MongoDB.log --logappend --serviceName MongoDB --install
  说明: --dbpath 设置数据库目录
     --directoryperdb 为每个数据库创建一个单独目录
--logpath 设置日志文件目录
--logappend 日志文件Append方式
--serviceName 服务名称
--install 安装
其他参数设置 >mongod --help


mongod.exe --dbpath D:\mongo3.4.10\data --directoryperdb --logpath D:\mongo3.4.10\log\MongoDB.log --logappend --serviceName MongoDB --install

安装mongoose会遇到的几个问题:
这些问题的解决方案参考一下几个链接
https://blog.csdn.net/heshushun/article/details/77776706
https://blog.csdn.net/bklydxz/article/details/50765071
https://blog.csdn.net/gebitan505/article/details/48052273

for (let i = 0; i < 3; i++) {
let tmpSeat = this.chairToView(i);
let text = new eui.Label;
text.fontFamily = "Arial";
text.size = 30;
text.bold = true;
//text.text = r.bomscore[i] > 0 ? ("+" + r.bomscore[i]) : ("" + r.bomscore[i]);
text.textAlign = "left";
text.textColor = 0x07FF00;
if (r.scores[i] < 0) {
text.textColor = 0xFF0000;
}
if (tmpSeat == 0) {
text.x = this.grpBottom.x + 150;
text.y = this.grpBottom.y + 60;

this.txtGold.text = "" + r.scores[i];
}
else {
text.x = this["group" + tmpSeat].x + 150;
text.y = this["group" + tmpSeat].y + 60;
if (tmpSeat == 1) {
text.textAlign = "right";
text.x = this["group" + tmpSeat].x - 100;
}

this["group" + tmpSeat].setGold(r.scores[i]);
}
服务器开发环境搭建
服务器架构说明
游戏服务器基于Pomelo框架开发;
redis作为外存(内存数据库,作用类似于缓存);
mongodb作为磁盘数据库;
WebStorm10作为IDE。

服务器环境搭建步骤
第一步 安装MongoDB
打开目录:手机端开发工具及代理\ProjectTool\server,找到文件mongodb-win32-x86_64-2008plus-ssl-3.0.4-signed.msi
下面是简单的安装步骤,第一步:

 

第二步:选择自定安装(可以自己定义安装目录)

 

第三步:选择安装目录

 

注意:安装目录中不能出现中文,也不能出现空格(不要安装到默认的Program Files目录下面),不需要Server\3.0这种目录,简单粗暴将目录设置成如D:\MongoDB或者D:\Software\MongoDB这样。

第四步:安装完成!


第五步:新建文件夹
在安装目录下创建一个新目录:data\db
完整的路径如:D:\MongoDB\data\db

第六步:创建批处理命令
打开目录:手机端开发工具及代理\ProjectTool\server,找到文件start-mongodb.bat,将其拷贝到安装目录的bin目录下面
使用文本编辑器(如notepad++)打开start-mongodb.bat,将最后的路径改为自己的路径,如

第七步:创建快捷方式
右击start-mongodb.bat,选择“发送到\桌面快捷方式”

第二步 安装VS2010
共享盘 Soft\开发&网页目录下,VS2010ExpressCHS.iso
第三步 安装微软常用运行库
找到目录手机端开发工具及代理\ProjectTool,运行微软常用运行库合集2015.01.exe

第四步 安装nodejs
打开目录:手机端开发工具及代理\ProjectTool\server,运行node-v0.12.4-x64.msi
出现提示安装界面:

第二步:选择安装目录,这里安装在目录 D:\yiibai_worksp\nodejs 中,如下图:

注意:安装路径中不要有中文字符,也不要出现空格,将其放在与MongoDB同一根目录下,例如D:\nodejs或者D:\Software\nodejs
第三步:选择安装的模块和功能,这里全部安装,并添加到系统环境变量,如下图所示:

第四步:安装完成!

第五步:测试
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs.
File: test.js
console.log("Hello World")
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出结果:

第五步 安装pomelo
第一步 配置路径
配置 PYTHON=d:\Python27\python.exe(设置成你自己的路径)。注意不是path里面,而是和path同级的,直接在全局或者当前用户下配置。
保证环境变量path里面有 %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;
注: 这三个环境变量中貌似只有%SystemRoot%\system32这个环境变量有用,没具体试(没有他会报CreateProcessW找不到的错误)。

第二步 运行安装命令
找到nodejs的安装目录,运行命令:npm install -g pomelo

第三步 测试安装pomelo是否完成
在上一步的目录下,运行命令:pomelo --help


第四步 开始进行开发
同上目录下,运行命令pomelo init pomelo_demo
遇到如下的情况,选1

完成之后的目录如下


第五步 安装node modules
进入项目目录pomelo_demo,运行如下命令npm-install.bat

第六步 安装redis
打开目录:手机端开发工具及代理\ProjectTool\server,运行Redis-x64-2.8.21.msi。

 

注意:目录不要带中文和空格,图示的目录并不正确。


打开目录:手机端开发工具及代理\ProjectTool\server,找到文件start-redis.bat,将其复制到安装目录中
右击start-redis.bat,选择“发送到\桌面快捷方式”

至此,服务器的环境搭建完毕,要启动项目,运行桌面上的两个快捷方式,使用Webstorm打开手机掼蛋的工程,运行即可。


SQLSERVER 备份

DECLARE
@FileName VARCHAR(200),
@CurrentTime VARCHAR(50),
@DBName VARCHAR(100),
@SQL VARCHAR(1000)
SET @CurrentTime = CONVERT(CHAR(8),GETDATE(),112) + CAST(DATEPART(hh, GETDATE()) AS VARCHAR) + CAST(DATEPART(mi, GETDATE()) AS VARCHAR)
DECLARE CurDBName CURSOR FOR
SELECT NAME FROM Master..SysDatabases where dbid>4
OPEN CurDBName
FETCH NEXT FROM CurDBName INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
--Execute Backup
SET @FileName = 'D:\hyf\' + @DBName + '_' + @CurrentTime
SET @SQL = 'BACKUP DATABASE ['+ @DBName +'] TO DISK = ''' + @FileName + '.bak' +
''' WITH NOINIT, NOUNLOAD, NAME = N''' + @DBName + '_backup'', NOSKIP, STATS = 10, NOFORMAT'
EXEC(@SQL)
--Get Next DataBase
FETCH NEXT FROM CurDBName INTO @DBName
END
CLOSE CurDBName
DEALLOCATE CurDBName

// virtual.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
using namespace std;
class Base
{
public:
//char a;
//char b;

int iValue;
//double c;

virtual void fun1(){
cout << "Base fun1" << endl;
fun2();
}
void fun2(){
cout << "Base fun2" << endl;
}
private:

};

class Derived :public Base{
public:
char* pValue;
virtual void fun1(){
fun2();
Base::fun1();
}
void fun2(){
cout << "Derived fun2" << endl;
}
};

class MoreDerived :public Derived{
public :
static double dValue;
//int a;
};
int _tmain(int argc, _TCHAR* argv[])
{
//Base b;
cout << sizeof(Base) << endl
<< sizeof(Derived) << endl
<< sizeof(MoreDerived) <<endl;

Derived d;
Base &rB = d;
rB.fun1();
Base* pB = &d;
pB->fun1();
pB = &((Base)d);
pB->fun1();
return 0;
}

//输出:

8
12
12
Derived fun2
Base fun1
Base fun2
Derived fun2
Base fun1
Base fun2
Base fun1
Base fun2

1.结构体每个成员相对于结构体首地址的偏移量(offset)都是(这个)成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internaladding);

例如有以下一个结构体

structex {
int i;
char t;
int n;
}
第1个成员偏移量为0,是int型成员大小4(假设这太机器的整型长度占4个字节)的整数倍。

第2个成员t为char型,他的大小为1,首先假设在成员i和t之间没有填充字节,由于i是整型,占4个字节那么在没有填充之前,
第2个成员t相对于结构体的偏移量为4,他是t成员大小1的4倍,符合此条件,所以系统在给结构体第2个成员分配内存时,不会在i和t之间填充字节以到达对齐的目的。

当分配结构体第3个成员n时,首先发现是一个整型数据,大小为4,没有填充之前,n相对于结构体首地址偏移量为:前面2个成员+填充字节=5,
所以当系统发现5不是4(成员大小)的整数倍时,会在成员t之后(或者说n之前)填充3个字节,以使n的偏移量到达8而成为4的整数倍。这样这个结构体占用内存情况暂时为4+1+3+4。

2.结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailingpadding)

posted on 2018-08-02 16:59  薄荷味的笑  阅读(105)  评论(0编辑  收藏  举报