Как отправить пакет XMPP IQ в PHP JAXL-Script?
У меня проблема. Я использую Asmack для подключения и отправки данных между Android и OpenFire.
Теперь я хотел бы получить эти данные с помощью PHP и Jaxl (который работает нормально).
Проблема в том, что я изменяю отправленное сообщение (в JSON и XML) и добавляю заголовок в 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();
}
}
Теперь у меня есть скрипт PHP CLI с JAXL. Это выглядит так.
<?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 здесь, который должен быть XEP для анализа пакета IQ.
$client->add_cb('on_chat_message', function($stanza) {
global $client;
$iq = $client->xeps['1337']->get_raw_iq_pkt();
// some more stuff
}
Теперь кажется, что $iq не содержит необработанных данных. Я не могу получить доступ к XML, что означает, что я не могу проанализировать пакет IQ.
XEP 1337 выглядит так.
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 Packages. Это единственное чтение, которое я нашел об этом ( 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>
Ошибка OpenFire =
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)
1 ответ
Вот что я узнал сейчас:
Its important that to has the fullname with ressource. user@domain/Ressource
И.. Получающий клиент должен быть онлайн. Автономные сообщения не принимаются для IQ PAckets от OpenFire (по умолчанию)
И.. в отношении этой статьи она должна быть как-то зарегистрирована. Как это можно сделать в jaxl? я думал, что добавление XEP и использование init() достаточно. Отправка и получение пользовательских IQ XMPP с помощью aSmack на Android
И.. я изменил 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());
}
}