KBEngine模块
KBEngine模块提供了Python脚本控制dbmgr进程处理实体登陆查询与数据存取等部分。
成员函数
def getCustomCfg( key, default=None ):
def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
def delTimer( id ):
def deregisterAcceptFileDescriptor( fileDescriptor ):
def deregisterReadDataFileDescriptor( fileDescriptor ):
[废弃] def deregisterReadFileDescriptor( fileDescriptor ):
[废弃] def deregisterWriteFileDescriptor( fileDescriptor ):
def registerAcceptFileDescriptor( fileDescriptor, callback ):
def registerReadDataFileDescriptor( fileDescriptor, callback ):
[废弃] def registerReadFileDescriptor( fileDescriptor, callback ):
[废弃] def registerWriteFileDescriptor( fileDescriptor, callback ):
def writeFileDescriptor( fileDescriptor, data, callback ):
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):
def urlopen( url, callback, postData, headers ):
回调函数
def onDBMgrReady( ):
def onDBMgrShutDown( ):
def onReadyForShutDown( ):
def onSelectAccountDBInterface( accountName ):
成员函数文档
def getCustomCfg( key, default=None ):
启用版本: 2.8.2
功能说明:
从服务端配置文件的 <customCfg> 节点中读取一个自定义配置项。该接口只读,脚本层不能通过它修改配置值。
配置项使用统一的 <param> 节点描述:name 是脚本读取时使用的键,type 决定返回给Python脚本的对象类型,节点文本是配置值。desc 仅作为配置文件中的说明文字,运行时不会读取到内存中。
支持的 type:bool、int、float、string、dict、list。
当配置项存在时,返回值类型只由XML中的 type 决定,不通过 default 参数推断。当配置项不存在时,如果传入了 default 则返回 default;如果未传入 default 则返回 None。
配置示例:
<customCfg>
<param name="battle.maxPlayers" type="int" desc="max players per battle">100</param>
<param name="battle.enableRank" type="bool" desc="enable battle rank">true</param>
<param name="battle.speedScale" type="float" desc="battle speed scale">1.0</param>
<param name="battle.welcome" type="string" desc="welcome text">hello</param>
<param name="battle.dropRates" type="dict" desc="drop rate config">{"gold": 1.2, "item": 0.05}</param>
<param name="battle.spawnPoints" type="list" desc="spawn point ids">[1, 2, 3]</param>
</customCfg>例子:
import KBEngine
maxPlayers = KBEngine.getCustomCfg("battle.maxPlayers", 100)
enableRank = KBEngine.getCustomCfg("battle.enableRank", False)
dropRates = KBEngine.getCustomCfg("battle.dropRates", {})
spawnPoints = KBEngine.getCustomCfg("battle.spawnPoints", [])
# 不存在且未传default时返回None,不会抛出异常。
missingValue = KBEngine.getCustomCfg("battle.null")参数:
key: string,自定义配置项名称,对应 <param name="...">。
default: 可选参数,当配置项不存在时返回该值;如果未提供则返回 None。
返回:
配置存在时返回按 type 转换后的Python对象;配置不存在时返回 default 或 None。
def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
功能说明:
注册一个定时器,定时器由回调函数callbackObj触发,回调函数将在"initialOffset"秒后被执行第1次,而后将每间隔"repeatOffset"秒执行1次。
例子:
# 这里是使用addTimer的一个例子
import KBEngine
# 增加一个定时器,5秒后执行第1次,而后每1秒执行1次,用户参数是9
KBEngine.addTimer( 5, 1, onTimer_Callbackfun )
# 增加一个定时器,1秒后执行,用户参数缺省是0
KBEngine.addTimer( 1, onTimer_Callbackfun )
def onTimer_Callbackfun( id ):
print "onTimer_Callbackfun called: id %i" % ( id )
# if 这是不断重复的定时器,当不再需要该定时器的时候,调用下面函数移除:
# KBEngine.delTimer( id )参数:
initialOffset: float,指定定时器从注册到第一次回调的时间间隔(秒)。
repeatOffset: float,指定第一次回调执行后每次执行的时间间隔(秒)。必须用函数delTimer 移除定时器,否则它会一直重复下去。值小于等于0将被忽略。
callbackObj: function,指定的回调函数对象。
返回:
integer,该函数返回timer的内部id,这个id可用于delTimer移除定时器。
def delTimer( id ):
功能说明:
函数delTimer用于移除一个注册的定时器,移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除,不必要使用delTimer移除。 如果delTimer函数使用一个无效的id(例如已经移除),将会产生错误。
到KBEngine.addTimer参考定时器的一个使用例子。
参数:
id: integer,它指定要移除的定时器id。
def deregisterAcceptFileDescriptor( fileDescriptor ):
功能说明:
注销监听 socket 的 accept completion 回调。停止监听服务或关闭 listener 前应调用该接口,避免 listener 已关闭后仍收到迟到的 accept completion。
参数:
fileDescriptor: integer,已经通过 registerAcceptFileDescriptor 注册的监听 socket 文件描述符。
def deregisterReadDataFileDescriptor( fileDescriptor ):
功能说明:
注销已连接 socket 的 read completion/data 回调。关闭客户端连接前应先调用该接口,再关闭 socket,并从脚本自己的 _clients、缓存表等容器中移除该 fd。
参数:
fileDescriptor: integer,已经通过 registerReadDataFileDescriptor 注册的已连接 socket 文件描述符。
[废弃] def deregisterReadFileDescriptor( fileDescriptor ):
已废弃:
旧 readiness 读注销接口已经废弃。脚本需要根据 fd 类型选择新的注销接口,避免 listener fd 和普通连接 fd 共用一个注销入口导致误删。
请改用:
- listener fd:使用 deregisterAcceptFileDescriptor。
- 已连接 socket fd:使用 deregisterReadDataFileDescriptor。
调用该旧接口会直接报错,提示使用新的 completion API。
[废弃] def deregisterWriteFileDescriptor( fileDescriptor ):
已废弃:
旧 readiness 写注销接口已经废弃。新的写接口 writeFileDescriptor 按请求提交并自动在完成后清理内部写 handler,不需要脚本显式注销写 fd。
调用该旧接口会直接报错,提示使用新的 completion API。
def registerAcceptFileDescriptor( fileDescriptor, callback ):
功能说明:
注册监听 socket 的 accept completion 回调。该接口用于 listener fd,底层完成 accept 后会把已经建立连接的 client fd 交给脚本。脚本层不再监听“listener 可读”,也不应该再对 listener 调用 accept()。
这是新的 completion API,用于替代旧的 registerReadFileDescriptor 监听 listener 可读的写法。
回调函数格式:
def onAccept(listenerFD, clientFD, errorCode):
pass参数:
fileDescriptor: integer,监听 socket 的文件描述符。
callback: function,accept 完成后的回调函数。listenerFD 是监听 fd,clientFD 是新连接 fd,errorCode 为 0 表示成功,非 0 表示底层 accept 错误。
使用说明:
在 onAccept 中通常需要用 clientFD 构造脚本层 socket 对象并保存,避免对象被 GC 后 fd 被关闭;随后调用 registerReadDataFileDescriptor 注册读 completion。
def registerReadDataFileDescriptor( fileDescriptor, callback ):
功能说明:
注册已连接 socket 的 read completion/data 回调。底层完成 recv 后,直接把读取到的 bytes 数据交给脚本。脚本层不再监听“fd 可读”,也不应该再对该 fd 调用 recv(),否则会绕过底层 completion 队列和生命周期管理。
这是新的 completion API,用于替代旧的 registerReadFileDescriptor 监听普通连接可读的写法。
回调函数格式:
def onRead(fd, data, errorCode):
pass参数:
fileDescriptor: integer,已连接 socket 的文件描述符。
callback: function,读完成后的回调函数。fd 是连接 fd,data 是本次读取到的 bytes,errorCode 为 0 表示正常,非 0 表示读错误。
使用说明:
completion 只表示“本次底层 recv 已完成”,不保证业务协议包完整。脚本仍需要根据自己的协议做缓存与组包。如果 data 为空或 errorCode != 0,通常应该关闭连接,并先调用 deregisterReadDataFileDescriptor。
[废弃] def registerReadFileDescriptor( fileDescriptor, callback ):
已废弃:
旧 readiness 读通知接口已经废弃。completion 后端不再向脚本报告“fd 可读”,因为 listener 的正确语义是 accept completion,普通连接的正确语义是 read data completion。
请改用:
- listener fd:使用 registerAcceptFileDescriptor。
- 已连接 socket fd:使用 registerReadDataFileDescriptor。
调用该旧接口会直接报错,提示使用新的 completion API。
[废弃] def registerWriteFileDescriptor( fileDescriptor, callback ):
已废弃:
旧 readiness 写通知接口已经废弃。completion 后端不再向脚本报告“fd 可写”,脚本应在每次需要发送数据时直接调用 writeFileDescriptor,并通过 onWriteComplete(fd, bytesWritten, errorCode) 接收完成结果。
调用该旧接口会直接报错,提示使用新的 completion API。
def writeFileDescriptor( fileDescriptor, data, callback ):
功能说明:
提交一次异步写请求。data 必须是 bytes,底层会复制数据并加入发送队列;脚本不需要、也不应该再注册“fd 可写”回调。发送完成后会调用本次请求传入的 completion 回调。
这是新的 completion API,用于替代旧的 registerWriteFileDescriptor / deregisterWriteFileDescriptor 可写通知模式。
回调函数格式:
def onWriteComplete(fd, bytesWritten, errorCode):
pass参数:
fileDescriptor: integer,已连接 socket 的文件描述符。
data: bytes,需要发送的数据。
callback: function,写完成后的回调函数。fd 是连接 fd,bytesWritten 是本次写请求完成的字节数,errorCode 为 0 表示成功,非 0 表示写失败。
使用说明:
每次调用都可以传入不同的回调。若连接是短连接,通常在 onWriteComplete 中关闭 fd;若是长连接,可以继续等待 registerReadDataFileDescriptor 的读回调。
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):
功能说明:
这个脚本函数在数据库上执行原始数据库命令,该命令将直接由相关数据库进行解析。
请注意使用该函数修改实体数据可能不生效,因为如果实体已经检出,被修改过的实体数据将仍会被实体存档而导致覆盖。
强烈不推荐这个函数用于读取或修改实体数据。
参数:
command:这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。
callback: 可选参数,带有命令执行结果的回调对象(比如说是一个函数)。这个回调带有4个参数:结果集合,影响的行数,自増长值,错误信息。
声明样例
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)如同上面的例子所示
result参数对应的就是"结果集合",这个结果集合参数是一个行列表。 每一行是一个包含字段值的字符串列表。
命令执行没有返回结果集合(比如说是DELETE命令), 或者 命令执行有错误时这个结果集合为None。
rows参数则是"影响的行数",它是一个整数,表示命令执行受影响的行数。这个参数只和不返回结果结合的命令(如DELETE)相关。
如果有结果集合返回或者命令执行有错误时这个参数为None。
insertid对应的是"自増长值",类似于实体的databaseID,当成功的向一张带有自増长类型字段的表中插入数据时,它返回该数据在插入时自増长字段所被赋于的值。 更多的信息可以参阅mysql的mysql_insert_id()方法。另外,此参数仅在数据库类型为mysql时有意义。
error则对应了"错误信息",当命令执行有错误时,这个参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。
threadID:int32,可选参数,指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序(dbmgr是多线程处理的),默认是不指定,如果threadID是实体的ID, 那么将加入到该实体的存档队列中由线程逐条写入。
dbInterfaceName: string,可选参数,指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。
def urlopen( url, callback, postData, headers ):
功能说明:
这个脚本函数在提供对外HTTP/HTTPS异步请求。
参数:
url: 有效的HTTP/HTTPS网址,字符串类型。
callback: 可选参数,带有请求执行结果的回调对象(比如说是一个函数)。这个回调带有5个参数:HTTP请求返回码(如:200) ,返回的内容,返回的HTTP协议头,是否成功,请求的网址。
声明样例:
def onHttpCallback(httpcode, data, headers, success, url):
print(httpcode, data, headers, success, url)如同上面的例子所示:
httpcode:参数对应的就是"HTTP请求返回码",这个结果集合参数是一个整形值。
data:参数则是"返回的内容",它是一个字符串。
headers:参数是"服务器返回的HTTP协议头",如:{"Content-Type": "application/x-www-form-urlencoded"},它是一个字典。
success:则对应了"执行是否成功",当请求执行有错误时,为False,可以通过httpcode进一步判断错误信息。
url:是"请求所用的网址。
postData: 可选参数,默认是GET方式请求服务器,如果需要POST方式请提供需要POST的内容,引擎将自动使用POST方式请求服务器,它是一个bytes。
headers: 可选参数,请求时使用的HTTP头,如:{"Content-Type": "application/x-www-form-urlencoded"},它是一个字典。
回调函数文档
def onDBMgrReady( ):
功能说明:
当前进程已经准备好的时候回调此函数。
注意
该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。
def onDBMgrShutDown( ):
功能说明:
进程关闭会回调此函数。
注意
该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。
def onReadyForShutDown( ):
功能说明:
如果这个函数在脚本中有实现,当进程准备退出时,该回调函数被调用。
可以通过该回调控制进程退出的时机。
注意
该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。
返回:
bool,如果返回True,则允许进入进程退出流程,返回其它值则进程会过一段时间后再次询问。
def onSelectAccountDBInterface( accountName ):
功能说明:
这个回调实现返回某个账号对应的数据库接口,选定接口后dbmgr针对这个账号的相关操作都由对应的数据库接口完成。
数据库接口在kbengine_defaults.xml->dbmgr->databaseInterfaces定义。
利用该接口可以根据accountName来决定账号应该存储在哪个数据库。
注意
该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。
参数:
accountName: string,账号的名称。
返回:
string,数据库接口名(数据库接口在kbengine_defaults.xml ->dbmgr->databaseInterfaces定义)。