1

我有问题。我使用 asmack 在 Android 和 OpenFire 之间连接和发送数据。

现在我想用 PHP 和 Jaxl 获取这些数据(工作正常)。

问题是我修改了发送的消息(到 JSON 和 XML)并将 HEADER 添加到 XML/JSON。这似乎运作良好,但它不是一个合适的解决方案。

现在我正在考虑发送已经包含标头信息的 IQ 包。

这是 Android/Java 中的部分。

      CommandIQPacket iq1 = new CustomIQPacket();
            iq1.setTo(to);
            iq1.setType(IQ.Type.GET);
            iq1.setCommand("test");
            iq1.setPriority(1);
            iq1.setJid(message.getMessage());
            iq1.setDate(new Date(System.currentTimeMillis()));
        mConnection.sendPacket(iq1);

CustomIQPacket 类扩展 IQ 并通过覆盖 getChildElementXML() 添加所需的数据。

样本:

public class CommandIQPacket extends IQ {


private int priority;
private String jid, command;
//some getter and setter

@Override
public CharSequence getChildElementXML() {

    StringBuilder builder = new StringBuilder("<query xmlns=\"urn:xmpp:ts\">");
    builder.append("<jid command=\"");
    builder.append(command).append("\"");
    builder.append(" date=\"");
    builder.append(date).append("\"");
    builder.append(" priority=\"");
    builder.append(priority).append("\"");
    builder.append(">");
    builder.append(jid);
    builder.append("</jid>");
    builder.append("</query>");
    return builder.toString();

}

}

现在我有了带有 JAXL 的 PHP CLI 脚本。这看起来像这样。

 <?php

  // configs, stuff, etc. 

$client = new JAXL(array(
'jid' => "myopenfireuser",
'pass' => "myopenfirepass",
'bosh_url' => "http://url-to-bosh.com:7070/http-bind/",
'log_level' => JAXL_INFO,
'strict' => TRUE
    ));

$client->require_xep(array(
'0115', // Entity Capabilities
'0203', // Delayed Delivery
'0114', // jabber component protocol
'1337'
));

我这里加了1337,应该是解析IQ包的XEP。

$client->add_cb('on_chat_message', function($stanza) {
global $client;

$iq = $client->xeps['1337']->get_raw_iq_pkt();
  // some more stuff
}

现在似乎 $iq 不保存任何原始数据。我无法访问 XML,这意味着我无法解析 IQ 包。

1337 XEP 看起来像这样。

class XEP_1337 extends XMPPXep {

public function init() {
    return array(
        'on_get_iq' => 'on_xmpp_iq'
    );
}

public function get_raw_iq_pkt() {

    $attrs = array(
        'type' => 'get',
        'from' => $this->jaxl->full_jid->to_string(),
        'to' => $this->jaxl->full_jid->domain
    );

    return $this->jaxl->get_iq_pkt(
                    $attrs, new JAXLXml('query', "ts")
    );
} 
}

我找不到任何关于 JAXL 和 IQ 包的好教程。这是我找到的唯一自述文件(https://media.readthedocs.org/pdf/jaxl/latest/jaxl.pdf

发送的数据例如

 <iq id='qEfml-14' to='openfirebot@openfirebot.com/Ressource' type='get'><query xmlns="ts"><jid command="test" date="Mon Jul 28 12:36:15 MESZ 2014" priority="1">...</query></iq>

openfire (jaxl) 的返回值是

<iq type="error" id="NP3HP-12" from="bot..@myopenfire.com" to="maclient@ts.com/Ressource"><query xmlns="ts" action="create"><jid command="test" date="Mon Jul 28 23:04:22 MESZ 2014" priority="1">...</jid></query><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>

开火错误=

     at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:283) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51) 
at java.lang.Thread.run(Thread.java:701) 
2014.07.29 15:56:33 org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to error while processing message: <iq id="769-83772" to="ts.com" from="ts.com/4140f14a" type="result"></iq> 
java.lang.NullPointerException 
at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:115) 
at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:76) 
at org.jivesoftware.openfire.net.StanzaHandler.processIQ(StanzaHandler.java:330) 
at org.jivesoftware.openfire.net.ClientStanzaHandler.processIQ(ClientStanzaHandler.java:93) 
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:295) 
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:187) 
at org.jivesoftware.openfire.nio.ConnectionHandler.messageReceived(ConnectionHandler.java:181) 
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570) 
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299) 
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53) 
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648) 
at org.apache.mina.common.IoFilterAdapter.messageReceived(IoFilterAdapter.java:80) 
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299) 
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53) 
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648) 
at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58) 
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:185) 
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299) 
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53) 
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648) 
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:239) 
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:283) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51) 
at java.lang.Thread.run(Thread.java:701) 
4

1 回答 1

0

这是我现在发现的:

Its important that to has the fullname with ressource.  user@domain/Ressource

并且.. 接收客户端必须在线。来自 OpenFire 的 IQ PAcket 不接受离线消息(默认情况下)

而且..关于这篇文章,它必须以某种方式注册。如何在 jaxl 中做到这一点?我认为添加 XEP 并使用 init() 就足够了。 在 Android 上使用 aSmack 发送和接收自定义 XMPP IQ

而且.. 我修改了 PAcketListener 但结果仍然相同。

        PacketFilter filter = new PacketFilter() {
            @Override
            public boolean accept(Packet packet) {
                return true;
            }
        };

        mConnection.addPacketListener(mPacketListener, filter);
        ProviderManager.addIQProvider("query", "ts", new CommandIQProvider());

而 mPacketListener 是从 PacketListener 扩展而来的类。

 public class ChatPacketListener implements PacketListener {

public void processPacket(Packet packet) {
    if (packet instanceof  Message) {
        Message message = (Message) packet;
        String from = message.getFrom();
        if (message.getBody() != null) {

            Log.d("ChatPacketLsitener", "XMPP packet received - sending Intent: " + XmppService.ACTION_XMPP_MESSAGE_RECEIVED);
            XmppService.maybeAcquireWakeLock();
            XmppTools.startSvcXMPPMsg(mCtx, message.getBody(), from);
        }
    } else {
        Log.e("Packet", "Packet is not from type Message. Its from type " + packet.getClass());

    }
}
于 2014-07-29T13:33:52.680 回答