如何使用Java Smack库连接XMPP BOSH服务器?

4

我正在使用strophe.js在webapp上工作的xmpp客户端,根据我的用例场景,我必须快速切换到不同的页面。

当前的方法不安全,因为jid和密码在java脚本中可见,我正在寻找解决方案,在strophe客户端中实现安全性,并尝试使连接时间(使用bosh)更短。当我阅读jake moffitt的《使用JavaScript和jQuery进行XMPP编程》时,我发现了一个解决方案,可以解决我的以上两个问题,即实现会话机制。它说我们可以使用strophe attach(jid,sid,rid)来连接现有的连接,所以我需要SID和RID,这些可以从应用服务器获取!

书中给出了一个例子,当用户登录Web应用程序时自动连接到bosh服务器,作者使用Python中的Django项目进行了实现。由于我使用Java作为服务器端语言,我尝试使用Java Smack-4.0.3和Smack-bosh-4.0.3实现相同的示例,但无法连接到bosh服务器(我正在使用ejabberd作为XMPP服务器)。

我的代码如下:

 BOSHConfiguration config = new BOSHConfiguration(false,"192.168.0.106",5280,"/http-bind/","192.168.0.106");
                XMPPBOSHConnection xbc=new XMPPBOSHConnection(config); 
                xbc.connect();
                xbc.login("admin", "admin");
                System.out.println(xbc.getConnectionID());

堆栈跟踪

java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
    at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:352)
    at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:347)
    at org.jivesoftware.smack.SmackConfiguration.<clinit>(SmackConfiguration.java:155)
    at org.jivesoftware.smack.ConnectionConfiguration.<init>(ConnectionConfiguration.java:67)

当我尝试登录BOSH服务器时,每次都失败了,我不确定出了什么问题,请问有人能解释一下吗?
还有一件事情我发现可以使用“xbc.getConnectionID()”获取会话标识符(SID),但如何找到请求标识符?
非常感谢您提前的帮助!
3个回答

4
我遇到了类似的问题。我从/smack-bosh中下载了所有内容Smack Github,并将smack.jar从/lib/导入,并添加了/src/main/java/org/jivesoftware/smack/中的3个Java文件。
我试图通过从/target/导入smack-bosh-3.2.2-jar-with-dependencies.jar来解决它。我不知道为什么这没起作用。
最后,我在这里阅读到,您需要下载所有依赖库: jbosh-0.6.0.jar xlightweb-2.5.jar xSocket-2.4.6.jar xpp3-1.1.3.3.jar dom4j-1.6.1.jar 所以,我使用/lib/中的smack.jar和所有这些库,问题得到了解决。
正如我在注释中所说,您需要检索RID。我使用jbosh源代码并添加以下行:
In com.kenai.jbosh.BOSHClient class
//I introduced a new property
private Long rid;

//commented the following code
//long rid = requestIDSeq.getNextRID();
//and at that place added
this.rid = requestIDSeq.getNextRID();

//and finally added a new getter for rid
public Long getRid() {
    return rid;}

然后在Smack-Bosh中:
In BOSHConnection.java
public Long getRid() {
    return client.getRid();}
public String getSid() {
    return sessionID;}

现在我被阻止了,因为我的会话已经断开连接。根据我的OpenFire日志,这是由于过度活动。因此,我正在寻找减少出席消息数量的解决方案。


显然,您可以通过BOSHConnection.getConnectionID直接访问Sid。 对于Rid来说,情况更加复杂。我必须处理jbosh库的源代码。现在我能够检索到一个Rid。我还没有测试过它。但是想法是在BOSHClient中添加一个getter来获取Rid,在BOSHConnection中使用前一个getter。一旦我测试过,我会告诉您。 此外,直接将.java文件导入我的项目并不起作用,所以我不得不修改bosh的.java文件,然后重新编译它们,生成新的.class文件和新的.jar文件进行导入。 - GuiguiDt
还有一件事我想问你,现在我已经添加了jbosh的源代码(所有Java文件),以便进行修改,但是当我创建了一个jar包并将其添加到我的项目中后,当我尝试连接BOSH管理器时,它会给我返回错误...说服务器没有响应!!!你有什么想法怎样可以在Eclipse中创建一个.jar文件吗? - Dev
1
嗨,在回答上面的“我还有一个问题......”(可能最好作为单独的问题!)时。 你需要知道SID是“会话ID”-因此,这个从服务器连接然后通过attach()传递的技巧可在两个http“会话”中使用相同的XMPP会话-在附加之前不能关闭服务器上的连接,否则会话会在XMPP服务器中被清理掉(我想)。请参见http://stackoverflow.com/a/23287076/1265200-我还必须更改代码以停止在服务器连接时发出存在标记。 - Dazed
1
对于.jar文件,我将jbosh源代码放入我的项目中,然后通过自动编译检索到.class文件,再用Winrar将其引入原始的jbosh.jar文件中。 同意Dazed关于“仅剩一个问题”的看法,否则会很混乱。 Dazed,请您解释一下您最后一句话的意思,谢谢。 - GuiguiDt
1
@user3523641 我不确定原因是什么,对我来说它直接运行得很好,我尝试只导入修改后的 .class(保留大部分原始代码),并确保导入所有修改后的部分:我注意到 BOSHClient 有3个 .class文件,一个原始文件和另外两个以 $1 和 $2 结尾的文件。但目前我没有看到特定的原因,如果我找到了一个,我会告诉你的。 - GuiguiDt
显示剩余8条评论

3
为了获得 Android BOSH 的最新优势,您需要使用 Smack Releases 4.1.1。
SMACK --- smack-tcp smack-sasl-provided smack-resolver-minidns smack-resolver-dnsjava smack-extensions smack-core smack-bosh smack-android-extensions smack-android。
此外,您还需要 XPP3 1.1.4c,从 JAR 文件中删除 javax 包,因为 android 已经有了 javax....QName 类。
JXMMP、JXMMP CACHE、JBOSH、MINIDNS、DNSJAVA、JSTUN、XBILL DNS。
不需要 Apache HTTP Client,因为它已经在 Android 中可用。
不幸的是,这需要大约 12 个 JAR 文件,最好在 Eclipse 中使用 Maven Android 项目。
否则,请在 Maven Central http://search.maven.org/#search 搜索上述关键字并逐个获取 JAR 文件。

1
我已经从smack-bosh中删除了SaslException。下一个版本应该可以在Android上无需修改即可正常工作。如果您将此报告给Smack社区论坛,我可能会更早地删除它。另外请注意,jstun和xbilldns(dnsjava)不是必需的。 - Flow

1
堆栈跟踪(stack trace)
java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
    at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:352)
    at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:347)
    at org.jivesoftware.smack.SmackConfiguration.<clinit>(SmackConfiguration.java:155)
    at org.jivesoftware.smack.ConnectionConfiguration.<init>(ConnectionConfiguration.java:67)

这里的异常明确表示Webapp找不到类org.xmlpull.v1.XmlPullParserFactory。这听起来像是您的类路径中缺少xml-apis库,(或者缺少其他实现XmlPullParser接口的库)。

感谢您的回答,正如@Deuteu所提到的那样,我没有包含xlightweb-2.5.jar,因此我遇到了上述问题。 - Dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接