sqlite3Plugin概览
使用sqlite通过网络存储游戏或会话数据
游戏通常需要一个服务器存储会话信息,例如所有正在运行的游戏,或者在游戏中的所有玩家,或者两者都有。这个服务器称为主服务器,由商业服务提供,通常有很高的租用费用。然而,这些服务器的核心是仅仅提供了一个类似于如下的画的一个数据库表格。
先前的几个RakNet版本使用LightweightDatabase提供这项服务。它是一个数据库的C++实现,使用了适当的接口。然而,这个工具有一些性能问题,并且难于使用,灵活性也比sql差很多。作为一个替代,sqlitePlugin出现了。它允许客户端在一个运行了sqlite的远端系统上(一个主机服务器)执行sql语句。
为什么不直接使用sqlite?默认情况下,sqlite仅仅对于文件操作有效。游戏需要通过一个真正的网络连接来执行语句。sqlite3Plugin解决了这个问题,它通过使用PacketizedTCP或者RakPeerInterface来传输语句,将语句解析成为结构体,然后将它发送回给用户。因为它是一个RakNet插件,在玩家连接或断开连接时,你也会访问到时间回调。以及这些玩家的信息。
sqlite是一个公共域软件,包含在了RakNet发布包中,位于DependentExtensions\sqlite3Plugin。
对于客户端和服务器,将插件附加到PacketizedTCP或者RakPeerInterface实例上。从sqlite3PluginInterface派生,实现函数来执行这些时间发生时想要实现的处理。使用插件注册你的派生类。
仅仅在服务器端,在执行任何语句之前,你需要设置sqlite连接。下面的例子在内存中创建了一个sqlite连接:
sqlite3_open_v2(":memory:",&database,sqlITE_OPEN_READWRITE | sqlITE_OPEN_CREATE,0);
sqlite3_open_v2方法的细节,或其他的命令,参考他们的帮助手册http://www.sqlite.org/c3ref/open.html。
将打开的数据库使用ADDDBHandle()方法传递到插件中。ADDDBHandle()方法的dbIdetifier参数仅仅是一个使用指针查找关联,可以是任何你想要的值。让这个参数与数据库文件的地址相同时才会有意义。
在客户端,可以使用sqlite3Plugin::_sqlite3_exec方法发送语句。服务器会相应,结果的处理回调会被调用,使用sqlite3PluginResultInterface::_sqlite3_exec处理成功调用sqlite3PluginResultInterface::OnUnknownDBIdentifier用于处理错误(未知数据库标示符)。
不要忘记转换用户输入!RakString::sqlEscape()方法可以用于实现这个功能。它会在任何引号,双引号,或者反斜线之前加一个反斜线。
这个系统默认是不安全的,默认情况下任何人可以执行任何查询。如果你想要安全性,你可以从sqlite3Plugin派生类,从而控制谁可以发送查询等。或者在数据库本身添加各种限制。
注释或者不注释sqlitePlugin.h文件中的sqlITE3_STATEMENT_EXECUTE_THREADED来控制是否在线程中执行语句。通常默认这一项是不注释的,因此在语句执行中阻塞并不阻塞你的程序。
因为这个系统的目的在于替代LightweightDatabase插件,样例sqlite3Sample.cpp显示了如何自动执行最重要的函数,这些功能是增加或删除连接和断开的连接的IP地址。你可以修改或从样例实现中派生,来增加更多你需要的功能。
参考样例工程DependentExtensions\sqlite3Plugin中本系统的实现。
原文链接:https://www.f2er.com/sqlite/200031.html