数据库配置 SmartFoxServer 2X

数据库配置

在本节中,我们将演示SFS2X与外部数据库之间的集成示例。我们使用MySQL的所有食谱,但您可以轻松地使用您选择的任何其他数据库(请阅读本教程)。我们在所有代码中使用标准SQL,因此可以将其移植到任何其他RDBMS。

自定义登录数据库
查询数据库和发送结果集
多个DB连接

配方#1 - 使用数据库自​​定义登录

该配方讨论了您需要根据存储在数据库中的用户配置文件验证客户端凭据的常见情况。我们还将展示如何在登录后立即执行更多的自定义逻辑,例如设置用户变量并从服务器端加入房间。

在服务器端实现自定义登录是一个简单的过程。 SFS2X启动两个登录事件:

USER_LOGIN:客户端请求加入区域时触发。在这里,您可以验证客户端凭据,并确定用户是否可以继续登录过程。在这个阶段,客户端被表示为Session对象,而不是SFSUser。
USER_JOIN_ZONE:当客户端成功加入Zone(并已变成SFSUser)时通知。

提供的示例附带一个可用于生成扩展使用的数据库表的MySQL转储(下载链接在本配方末尾提供)。这些是设置和测试示例应用程序的步骤。

我们需要一个名为sfs2x的数据库,如果没有,请创建它。
使用提供的muppets-table.sql文件将“muppets”表导入数据库。这包含一些可用于测试登录的登录帐户。
通过将扩展名复制到{sfs-install-dir} / SFS2X / extensions /的子文件夹中。您可以为子文件夹选择任何名称,例如muppetsExt。
启动AdminTool,选择Zone Configurator模块并编辑BasicExamples区域。设置区域的扩展名如下:
    名称:muppetsExt(或您选择的名称,如果不同)
    类型:JAVA
    主类:sfs2x.extension.test.dblogin.DBLogin
在“区域配置器”的“常规”选项卡中,确保激活自定义登录选项。
此时,您应该准备重新启动SFS2X,除非您还需要设置数据库连接。如果您以前没有这样做,我们建议您遵循HowTo教程。

您现在可以启动提供的客户端并测试该扩展。
»登录处理程序

LoginEventHandler类是我们检查凭据的地方。在此示例中,我们访问DBManager连接并使用PreparedStatement对象,以便使用参数构建查询并对外部参数中的可能的错误字符进行清理。

// Grab a connection from the DBManager connection pool从DBManager连接池抓取一个连接
connection = dbManager.getConnection();

// Build a prepared statement构建一个准备好的语句
PreparedStatement stmt = connection.prepareStatement("SELECT pword,id FROM muppets WHERE name=?");
stmt.setString(1, userName);

// Execute query执行查询
ResultSet res = stmt.executeQuery();

作为这种方法的替代方法,您可以使用DBManager.executeQuery(String sql,Object [] params)方法,其工作方式类似,无需在连接级别工作。 我们没有使用这个例子,因为在写入时它还不可用(需要SmartFoxServer 2X版本RC1b或更高版本)。

遇到错误(例如,错误的密码)时,我们引发SFSLoginException类型的异常并提供一个附加的错误代码:

if (!getApi().checkSecurePassword(session, dbPword, cryptedPass))
{
    SFSErrorData data = new SFSErrorData(SFSErrorCode.LOGIN_BAD_PASSWORD);
    data.addParameter(userName);

    throw new SFSLoginException("Login failed for user: "  + userName, data);
}

在使用不当的用户名或密码错误的情况下,我们还会指定使用的名称或密码,以便将其报告给客户端。
»处理异常

使用数据库时要牢记的一个重要方面是正确处理异常。 如果SQL语法等存在问题,则对数据库的任何调用都可能会发生错误,因此确保连接在任何cas中关闭至关重要,否则将泄漏并最终强制连接池 。 处理异常的最佳方式如下:

try
{
    connection = dbManager.getConnection();
    // Your database code goes here你的数据库代码到这里
}
catch(SQLException sqle)
{
    // Here we handle the SQL failure这里我们处理SQL失败
}
finally
{
    try
    {
        connection.close();
    }
    catch(SQLException sqle)
    {
        // It shouldn't happen, but if it does it's best to leave a trace in the logs它不应该发生,但如果最好在日志中留下痕迹
    }
}

finally块确保在离开该方法之前连接被关闭,并且close()方法周围的附加try / catch块处理连接返回到池时发生错误的罕见可能性。
»登录后处理程序

当通知USER_JOIN_ZONE事件时,我们准备与用户进行更多的工作,该用户现在已完全登录到系统中。 ZoneJoinEventHandler类设置“dbID”用户变量,用户ID来自数据库,最后将用户加入主厅。

public class ZoneJoinEventHandler extends BaseServerEventHandler
{
    @Override
    public void handleServerEvent(ISFSEvent event) throws SFSException
    {
        User theUser = (User) event.getParameter(SFSEventParam.USER);

        // dbid is a hidden UserVariable, available only server side  dbid是一个隐藏的UserVariable,仅可用的服务器端
        UserVariable uv_dbId = new SFSUserVariable("dbid", theUser.getSession().getProperty(DBLogin.DATABASE_ID));
        uv_dbId.setHidden(true);

        // The avatar UserVariable is a regular UserVariable 头像UserVariable是一个常规的UserVariable
        UserVariable uv_avatar = new SFSUserVariable("avatar", "avatar_" + theUser.getName() + ".jpg");

        // Set the variables设置变量
        List<UserVariable> vars = Arrays.asList(uv_dbId, uv_avatar);
        getApi().setUserVariables(theUser, vars);

        // Join the user加入用户
        Room lobby = getParentExtension().getParentZone().getRoomByName("The Lobby");

        if (lobby == null)
            throw new SFSException("The Lobby Room was not found! Make sure a Room called 'The Lobby' exists in the Zone to make this example work correctly.没有找到大厅了!”确保一个叫做“大厅”的房间存在于该区域,以使此示例正常工作。");

        getApi().joinRoom(theUser, lobby);
    }
}

配方#2 - 查询数据库和发送结果集

该配方显示了如何从数据库读取数据并以便利的格式将其发送给客户端。服务器端的SFSDBManager.executeQuery方法提供了一种执行SQL查询并获取基于SFSArray的数据结构的有效方式,可以即时发送到客户端。
有关这方面的更多细节,我们建议您参考SFSDBManager javadoc。

在这个简单的例子中,我们将从人员数据库中获得一个记录列表,并通过几行代码将它们发送给客户端。

来源附带一个可用于生成扩展使用的数据库表的MySQL转储(下载链接在本配方末尾提供)。这些是设置和测试示例应用程序的步骤。

我们需要一个名为sfs2x的数据库,如果没有,请创建它。
使用提供的people-table.sql文件将'people'表导入数据库。
将扩展名复制到{sfs-install-dir} / SFS2X / extensions /的子文件夹中。您可以为子文件夹选择任何名称,例如peopleExt。
启动AdminTool,选择Zone Configurator模块并编辑BasicExamples区域。设置区域的扩展名如下:
    名称:peopleExt(或您选择的名称,如果不同)
    类型:JAVA
    主类:sfs2x.extension.test.people.PeopleExtension
在“区域配置器”的“常规”选项卡中,确保关闭了自定义登录。
此时,您应该准备重新启动SFS2X,除非您还需要设置数据库连接。如果您以前没有这样做,我们建议您遵循HowTo教程。

您现在可以启动提供的客户端并测试该扩展。
»请求处理程序

在源代码中,您会发现一个GetPeopleHandler类,它响应来自客户端的“getPeople”请求。我们来看看它的作用:
public class GetPeopleHandler extends BaseClientRequestHandler
{
@Override
public void handleClientRequest(User sender, ISFSObject params)
{
IDBManager dbManager = getParentExtension().getParentZone().getDBManager();
String sql = “SELECT * FROM people”;

    try
    {
        // Obtain a resultset 获取结果集
        ISFSArray res = dbManager.executeQuery(sql, new Object[] {});

        // Populate the response parameters 填充响应参数
        ISFSObject response = new SFSObject();
        response.putSFSArray("people", res);

        // Send back to requester 发送回请求者
        send("getPeople", response, sender);
    }
    catch (SQLException e)
    {
        trace(ExtensionLogLevel.WARN, "SQL Failed: " + e.toString());
    }
}

}
返回的SFSArray包含表示为SFSObject的所有记录,这使得很容易提取字段值。 这是在处理EXTENSION_RESPONSE事件时如何在客户端(ActionScript 3)上完成的:

private function onExtensionResponse(evt:SFSEvent):void
{
    var params:ISFSObject = evt.params.params as ISFSObject
    var peopleArray:ISFSArray = params.getSFSArray("people")

    var dump:String = "PEOPLE LIST RECEIVED:\n\n"

    for (var i:int = 0; i < peopleArray.size(); i++)
    {
        var item:ISFSObject = peopleArray.getSFSObject(i)
        dump += "    > " + item.getUtfString("name") + ", " + item.getUtfString("location") + ", " + item.getUtfString("occupation") + "\n"
    }

    dTrace(dump)
    dTrace("Total records: " + peopleArray.size())
}

我们需要做的就是循环接收SFSArray中的每一个元素。 每个项目都是一个SFSObject,它表示结果集的一行,它允许我们以名称访问其字段。 在我们的例子中,字段名称是:名称,位置,职业。

配方#3 - 多个DB连接

可能有一种应用程序需要连接到多个数据库的情况。 默认情况下,SFS2X中的每个Zone都会暴露一个DBManager对象,但是我们可以通过代码创建更多的这些对象,以管理多个数据源。

我们强烈建议您在扩展程序的init()方法中创建所有必需的DBManager实例。 这是一个通过代码创建DBManager的例子:

public class MultiDBExtension extends SFSExtension
{
    private SFSDBManager dbm;

    @Override
    public void init()
    {
        // Prepare DBManager configuration 准备DBManager配置
        DBConfig cfg = new DBConfig();

        cfg.active = true;
        cfg.driverName = "com.mysql.jdbc.Driver";
        cfg.connectionString = "jdbc:mysql://127.0.0.1/database_name";
        cfg.userName = "db_user_name";
        cfg.password = "db_user_pass";
        cfg.testSql = "SELECT name FROM some_table LIMIT 1";

        //... more settings  更多设置 

        // Create DBManager创建DBManager
        dbm = new SFSDBManager(cfg);
    }
}

翻译自http://docs2x.smartfoxserver.com/DevelopmentBasics/database-recipes

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值