Smack android 传入的 onStanza 与调试器不同
Smack android incoming onStanza is different from debugger
windows 上的 Gajim 客户端和 smack debbuger return 这种节,与 xmpp 规范中的相同。
<message id='aeb213' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:2' queryid='f27' id='28482-98726-73623'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
<message xmlns='jabber:client' from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
<body>Hail to thee</body>
</message>
</forwarded>
</result>
</message>
然而在 onStanza
中它 return 是这个:
<message to="juliet@capulet.lit/chamber" from="juliet@capulet.lit/chamber">
<result xmlns="urn:xmpp:mam:0">
<body>Hail to thee</body>
<stanza-id/>
<delay/>
<archived/>
<data/>
</result>
</message>
你如何解决这个问题?这是部分代码。
public class XmppServiceSmackImpl implements XmppService, StanzaListener, ConnectionListener {
XmppServiceListener xmppServiceListener;
Logger logger = Logger.getLogger(XmppServiceSmackImpl.class.getName());
XMPPTCPConnection connection;
String password;
public XmppServiceSmackImpl(XmppServiceListener xmppServiceListener) {
this.xmppServiceListener = xmppServiceListener;
}
@Override
public void setup(String jid, String password, String authMethod, String hostname, Integer port) {
final String[] jidParts = jid.split("@");
String[] serviceNameParts = jidParts[1].split("/");
String serviceName = serviceNameParts[0];
XMPPTCPConnectionConfiguration.Builder confBuilder = XMPPTCPConnectionConfiguration.builder()
.setServiceName(serviceName)
.setUsernameAndPassword(jidParts[0], password)
.setConnectTimeout(3000)
//.setDebuggerEnabled(true)
.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
if (serviceNameParts.length>1){
confBuilder.setResource(serviceNameParts[1]);
} else {
confBuilder.setResource(Long.toHexString(Double.doubleToLongBits(Math.random())));
}
if (hostname != null){
confBuilder.setHost(hostname);
}
if (port != null){
confBuilder.setPort(port);
}
if (trustedHosts.contains(hostname) || (hostname == null && trustedHosts.contains(serviceName))){
confBuilder.setCustomSSLContext(UnsafeSSLContext.INSTANCE.getContext());
}
XMPPTCPConnectionConfiguration connectionConfiguration = confBuilder.build();
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
connection = new XMPPTCPConnection(connectionConfiguration);
// Disable automatic roster request
Roster roster = Roster.getInstanceFor(connection);
roster.setRosterLoadedAtLogin(false);
roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
connection.addAsyncStanzaListener(this, null);
connection.addConnectionListener(this);
connection.addStanzaAcknowledgedListener(this);
}
@Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
logger.log(Level.WARNING, "Received stanza: " + packet);
this.xmppServiceListener.onStanza(packet);
}
}
属于 XEP-0280
在 SMACK 中,这是一项实验性功能。
您的 build.gradle
中需要额外的库
dependencies {
compile "org.igniterealtime.smack:smack-android-extensions:4.2.0"
}
在使用 SMACK 做任何事情之前,您必须初始化实验性功能:
new ExperimentalInitializer().initialize();
顺便说一下,provider 是一个类似插件的节处理程序
当您想在客户端和服务器之间使用自定义节时。
您必须编写自己的提供程序以将其解析为 Message 对象下的扩展元素。
看看 ProviderManager。
windows 上的 Gajim 客户端和 smack debbuger return 这种节,与 xmpp 规范中的相同。
<message id='aeb213' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:2' queryid='f27' id='28482-98726-73623'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
<message xmlns='jabber:client' from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
<body>Hail to thee</body>
</message>
</forwarded>
</result>
</message>
然而在 onStanza
中它 return 是这个:
<message to="juliet@capulet.lit/chamber" from="juliet@capulet.lit/chamber">
<result xmlns="urn:xmpp:mam:0">
<body>Hail to thee</body>
<stanza-id/>
<delay/>
<archived/>
<data/>
</result>
</message>
你如何解决这个问题?这是部分代码。
public class XmppServiceSmackImpl implements XmppService, StanzaListener, ConnectionListener {
XmppServiceListener xmppServiceListener;
Logger logger = Logger.getLogger(XmppServiceSmackImpl.class.getName());
XMPPTCPConnection connection;
String password;
public XmppServiceSmackImpl(XmppServiceListener xmppServiceListener) {
this.xmppServiceListener = xmppServiceListener;
}
@Override
public void setup(String jid, String password, String authMethod, String hostname, Integer port) {
final String[] jidParts = jid.split("@");
String[] serviceNameParts = jidParts[1].split("/");
String serviceName = serviceNameParts[0];
XMPPTCPConnectionConfiguration.Builder confBuilder = XMPPTCPConnectionConfiguration.builder()
.setServiceName(serviceName)
.setUsernameAndPassword(jidParts[0], password)
.setConnectTimeout(3000)
//.setDebuggerEnabled(true)
.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
if (serviceNameParts.length>1){
confBuilder.setResource(serviceNameParts[1]);
} else {
confBuilder.setResource(Long.toHexString(Double.doubleToLongBits(Math.random())));
}
if (hostname != null){
confBuilder.setHost(hostname);
}
if (port != null){
confBuilder.setPort(port);
}
if (trustedHosts.contains(hostname) || (hostname == null && trustedHosts.contains(serviceName))){
confBuilder.setCustomSSLContext(UnsafeSSLContext.INSTANCE.getContext());
}
XMPPTCPConnectionConfiguration connectionConfiguration = confBuilder.build();
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
connection = new XMPPTCPConnection(connectionConfiguration);
// Disable automatic roster request
Roster roster = Roster.getInstanceFor(connection);
roster.setRosterLoadedAtLogin(false);
roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
connection.addAsyncStanzaListener(this, null);
connection.addConnectionListener(this);
connection.addStanzaAcknowledgedListener(this);
}
@Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
logger.log(Level.WARNING, "Received stanza: " + packet);
this.xmppServiceListener.onStanza(packet);
}
}
属于 XEP-0280 在 SMACK 中,这是一项实验性功能。 您的 build.gradle
中需要额外的库dependencies {
compile "org.igniterealtime.smack:smack-android-extensions:4.2.0"
}
在使用 SMACK 做任何事情之前,您必须初始化实验性功能:
new ExperimentalInitializer().initialize();
顺便说一下,provider 是一个类似插件的节处理程序 当您想在客户端和服务器之间使用自定义节时。 您必须编写自己的提供程序以将其解析为 Message 对象下的扩展元素。 看看 ProviderManager。