配置 ejabberd 以用作游戏服务器

Posted

技术标签:

【中文标题】配置 ejabberd 以用作游戏服务器【英文标题】:Configuring ejabberd for use as a game server 【发布时间】:2013-01-16 00:05:18 【问题描述】:

我已经设置了一个 ejabberd 服务器,我只想用作游戏服务器。

关于安全性我需要注意哪些事项以及需要哪些步骤才能开始将其用作游戏服务器?当然,我想只启用本地用户之间的通信,可能无法从其他服务器与 JID 进行通信

如何禁用 IRC 和服务器到服务器等功能?这必须在ejabberd.cfg 中完成,对吧?我是否必须将这些段落注释掉或填写空括号以供他们选择?

我定义了以下访问控制列表:

[acl, admin, user, "admin", "localhost",
 acl, admin, user, "admin", "***.***.***.***",
 acl, local, server, "localhost",
 acl, local, server, "***.***.***.***"].

关于访问权限,以下定义是否可行,或者我应该禁用除 PubSub 之外的所有通信渠道?

[access, c2s, [deny, blocked, allow, all],
 access, pubsub_createnode, [allow, all],
 access, s2s_shaper, [fast, all],
 access, c2s_shaper, [none, admin, normal, all],
 access, muc, [allow, all],
 access, max_user_sessions, [2, all],
 access, configure, [allow, admin],
 access, muc_admin, [allow, admin],
 access, max_user_offline_messages,
  [5000, admin, 100, all],
 access, announce, [allow, admin],
 access, register, [deny, all],
 access, local, [allow, local]].

之后,我可以通过 smack / asmack 等客户端库访问服务器,还是需要 BOSH、HTTP 轮询等? XMPP 端口通常会在移动设备上打开吗?

以上这些安全考虑对我来说是最重要的,因为我不想运行有潜在安全风险的游戏服务器。但除此之外,我还不能真正运行 PubSub .

在客户端,在 android 应用程序中,我使用 asmack 库和以下代码来启动新的 XMPP 会话并发送消息:

private void startXMPP() 
    new Thread(new Runnable() 
        public void run() 
            try 
                org.jivesoftware.smackx.ConfigureProviderManager.configureProviderManager();
                ConnectionConfiguration xmppConfig = new ConnectionConfiguration("123.123.123.123");
                xmppConfig.setDebuggerEnabled(true);
                if (Build.VERSION.SDK_INT >= 14) 
                    xmppConfig.setTruststoreType("AndroidCAStore");
                    xmppConfig.setTruststorePassword(null);
                    xmppConfig.setTruststorePath(null);
                    xmppConfig.setSendPresence(true);
                    xmppConfig.setSecurityMode(SecurityMode.disabled);
                
                else 
                    xmppConfig.setTruststoreType("BKS");
                    String path = System.getProperty("javax.net.ssl.trustStore");
                    if (path == null) 
                        path = "/system/etc/security/cacerts.bks";
                    
                    xmppConfig.setTruststorePath(path);
                
                SASLAuthentication.supportSASLMechanism("PLAIN", 0);
                XMPPConnection xmpp = new XMPPConnection(xmppConfig);
                xmpp.connect();
                xmpp.login("john", "password");
                PubSubManager xmppPubsub = new PubSubManager(xmpp);
                ConfigureForm form = new ConfigureForm(FormType.submit);
                form.setPersistentItems(false);
                form.setDeliverPayloads(true);
                form.setAccessModel(AccessModel.open);
                form.setPublishModel(PublishModel.open);
                form.setSubscribe(true);
                LeafNode xmppNode;                  
                try 
                    xmppNode = (LeafNode) xmppPubsub.createNode("TESTNODE", form);
                
                catch (XMPPException e) 
                    xmppNode = (LeafNode) xmppPubsub.getNode("TESTNODE");
                
                SimplePayload payload = new SimplePayload("book", "pubsub:test:book", "");
                xmppNode.addItemEventListener(new ItemEventCoordinator<Item>());
                xmppNode.subscribe("john@123.123.123.123");
                xmppNode.publish(new PayloadItem<SimplePayload>(payload));
            
            catch (Exception e) 
                System.out.println("XMPP Connection failed!");
                e.printStackTrace();
            
        
    ).start();

很遗憾,这不起作用。你明白为什么吗?由于我启用了调试,我可以在 LogCat 中看到以下错误消息:

<iq from='pubsub.123.123.123.123' to='john@123.123.123.123/Smack' id='Jf****6' type='result'><pubsub xmlns='http://jabber.org/protocol/pubsub'><subscription jid='john@123.123.123.123' subscription='subscribed' subid='53******B2'/></pubsub></iq>

<iq id="Je4Mf-7" to="pubsub.123.123.123.123" type="set"><pubsub xmlns="http://jabber.org/protocol/pubsub"><publish node='TESTNODE'><item></item></publish></pubsub></iq>

<iq from='pubsub.123.123.123.123' to='john@123.123.123.123/Smack' type='error' id='Jf****7'><pubsub xmlns='http://jabber.org/protocol/pubsub'><publish node='TESTNODE'><item/></publish></pubsub><error code='400' type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><payload-required xmlns='http://jabber.org/protocol/pubsub#errors'/></error></iq>

编辑:

我没有按照文档中的说明将 PubSub 节点名称设置为 home/server/username/whatever。但至少节点的创建是有效的,不是吗?我不想要这种格式的名称,因为我需要诸如“game234234”之类的名称,以便所有参与用户都可以加入该 PubSub 节点。

此外,似乎有人尝试联系pubsub.***.***.***.***,但它不存在,因为我还没有创建子域pubsub。这是问题的原因吗? PubSub 是否只能通过该子域使用?我不知道为该子域设置什么,并且更愿意在没有子域的 IP 上使用 PubSub。

【问题讨论】:

【参考方案1】:

您的 publish() 命令出现错误,因为您没有指定实际负载。理想情况下,由于您创建了无效的有效负载,因此应该引发异常,但这似乎是您从服务器获取错误的根源。

改变

SimplePayload payload = new SimplePayload("book", "pubsub:test:book", "");

到:

SimplePayload payload = new SimplePayload("book", "pubsub:test:book", "<book xmlns='pubsub:test:book'>Romeo and Juliet</book>");

它应该会成功发布。

现在还有几个其他问题需要解决。

您正在运行方法中创建连接,该方法在 publish() 之后结束,因此您的连接超出范围并符合 GC 条件。

在创建之前尝试执行 getNode()。按照您当前的顺序,在您的代码第一次运行后,您将始终遇到异常情况。您应该先简单地执行 getNode(),然后在抛出异常时创建一个,或者您可以通过先执行 discoverNodes() 来确定是否完全避免异常节点存在。

至于您关于 pubsub 子域的观点。这是许多(可能是所有)XMPP 服务器(包括 ejabberd)中 pubsub 的常用子域。您不必创建它,因为 pubsub 模块已经这样做了。它确实已经存在,因为您已经收到了它的回复。

【讨论】:

以上是关于配置 ejabberd 以用作游戏服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CentOS 上扩展 ejabberd 服务器机器以处理 200 K 连接?

游戏服务器如何配置?

ejabberd 集群:多主或主从

Ejabberd 限制用户注册权限

如何在 ejabberd 服务器中配置 mysql?

使用 google Play 游戏服务配置 LIBGDX 游戏错误