2016-08-30 4 views
1

Я пытаюсь автоматизировать некоторые тесты сервера xmpp. Я отправляю xml-строфу на сервер xmpp и проверяю ответ. Я могу успешно отправить строфу, но у меня возникли проблемы с получением ответа.Как получить ответ IQ

Я использую Smack 4.1.8 api.

Это строфа, что я посылаю:

<iq id='123' from='[email protected]' to='[email protected]/resource' type='get'> 
<control xmlns='http://domain.com/powertalk/control/2.0'> 
<point id='00000000/relay_1A' /> 
<point id='00000000/relay_2A' /> 
</control> 
</iq> 

Когда я посылаю это с помощью клиента PSI я получаю следующее в ответ:

<iq from="[email protected]/resource" type="result" to="[email protected]/resource" id="17"> 
<control xmlns="http://domain.com/powertalk/control/2.0"> 
<point val="0" id="00000000/relay_1A" ts="2016-08-30T15:52:41.068308Z"/> 
<point val="0" id="00000000/relay_2A" ts="2016-08-30T15:52:41.148337Z"/> 
</control> 
</iq> 

Это то, что я хочу получить.

То, что я на самом деле получаете:

<iq to='[email protected]/resource' from='[email protected]' id='c8QbM-8' type='result'> 
<query xmlns='jabber:iq:roster'></query> 
</iq> 

Вот мой код. Я думаю, что мне нужно сделать какой-то пользовательский провайдер IQ, но примеры, которые я нахожу, в основном для Smack 3.x и недействительны.

 AbstractXMPPConnection mConnection = this.getConnection(); 
     try 
     { 
      final IQ iq = new IQ("control","http://domain.com/powertalk/control/2.0") 
      { 
       @Override 
       protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) 
       { 
        xml.rightAngleBracket(); 
        xml.halfOpenElement("point"); 
        xml.attribute("id", "00000000/relay_1A"); 
        xml.append(" />"); 
        xml.halfOpenElement("point"); 
        xml.attribute("id", "00000000/relay_2A"); 
        xml.append(" />"); 

        return xml; 
       } 
      }; 
      iq.setStanzaId("123"); 
      iq.setFrom("[email protected]"); 
      iq.setType(IQ.Type.get); 
      iq.setTo("[email protected]/resource"); 
      mConnection.sendStanza(iq); 

      // Receive the packet 
      IQ iqReceived = (IQ)collector.nextResult(50000); 

      // Stop queuing results 
      collector.cancel(); 

      System.out.println("Sent:  " + iq.toXML()); 
      System.out.println("Received: " + iqReceived.toXML()); 
      System.out.println("Collector size = " + collector.getCollectedCount()); //returns 0 
      System.out.println("collector pollResult = " + collector.pollResult()); //returns null 
      System.out.println("collector StanzaFilter = " + collector.getStanzaFilter()); //returns: StanzaIdFilter: id=123 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

    } 

Что мне здесь не хватает?

+0

Я предлагаю глядя на исходный код хлопать. Пинг-код XMPP - простой пример того, как отправлять сообщения IQ и слушать результаты. – Flow

+0

Вы используете плагин openfire для этого общения? – Saveen

+0

от того, что я понимаю в ping, он просто возвращает true/false. Я не вижу способ получить результат IQ с сервера. Можете ли вы объяснить, как я буду это делать и вернуть результат, который клиент PSI делает в моем примере выше? – user6776106

ответ

0

Я отказался от smack 4.1.8, и теперь я пытаюсь с smack 3.2.1 и изменил свой код. Я вижу, что вся моя строфа отправлена ​​и получена, как ожидалось.

Мой код просто возвращает первую строчку строфы:

<iq id="123" to="[email protected]/Smack" from="[email protected]/0004a369d964" type="result"></iq> 

Я включил привкусом отладчик, и я могу видеть весь результат строфу в окне отладчика.

Как я могу получить остальное?

Я ожидаю:

<iq from="[email protected]/resource" type="result"to="[email protected]/resource" id="123" 
<controlxmlns="http://domain.com/powertalk/control/2.0"> 
<point val="0" id="00000000/relay_1A" ts="2016-08-30T15:52:41.068308Z"/> 
<point val="0" id="00000000/relay_2A" ts="2016-08-30T15:52:41.148337Z"/> 
</control> 
</iq> 

вот мой код:

  final XMPPConnection mConnection = this.getConnection(); 
      this.login(); 

      IQConnectionRequest iq = new IQConnectionRequest("00000000/relay_1A", "00000000/relay_1A"); 

      iq.setTo("[email protected]/0004a369d964"); 
      iq.setFrom("[email protected]"); 
      iq.setPacketID("123"); 
      iq.setType(IQ.Type.GET); 

      PacketFilter filter = new AndFilter(new PacketIDFilter(iq.getPacketID()), 
        new PacketTypeFilter(IQ.class)); 
      PacketCollector collector = mConnection.createPacketCollector(filter); 
      // Send the iq packet with an invalid namespace 
      mConnection.sendPacket(iq); 

      IQ result = (IQ)collector.nextResult(50000); 
      // Stop queuing results 
      collector.cancel();    

      System.out.println("result.getType() = " + result.toXML()); 

      } 
0

Фигурные его. Поэтому, если кто-то заинтересован, вот мое решение. Это мой тест, вызывающий мой код. Метод

XmppMethods command = new XmppMethods(); 

    String result; 
    result = command.sendXMLCommand("123", "get", "00000000/relay_1A", "00000000/relay_2A"); 

    System.out.println("result = " + result); 

sendXMLCommand:

public String sendXMLCommand(String packetID, String type, String... points) throws IOException, XMPPException 
    { 
     ListIQ result = null; 
     try 
     { 
      this.makeConnection(); 
      final XMPPConnection mConnection = this.getConnection(); 
      ServiceProviders.Register_Providers(ProviderManager.getInstance()); 
      this.login(); 
      IQConnectionRequest iq = new IQConnectionRequest(packetID, type, points); 

      PacketFilter filter = new AndFilter(new PacketIDFilter(iq.getPacketID()), 
        new PacketTypeFilter(IQ.class)); 
      PacketCollector collector = mConnection.createPacketCollector(filter); 

      mConnection.sendPacket(iq); 

      result = (ListIQ)collector.nextResult(50000); 

      collector.cancel(); 


     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      this.disconnect(); 
     } 
     return result.toXML(); 

    } 

IQConnectionRequest

public class IQConnectionRequest extends IQ 
{   
    protected String[] points; 

    public String[] getPoints() 
    { 
     return points; 
    } 

    public void setPoints(String... points) 
    { 
     this.points = points; 
    } 


    @Override 
    public String getChildElementXML() 
    { 
     String body = "<control xmlns=\"http://domain_name.com/powertalk/control/2.0\">"; 

     for (int i = 0; i<this.points.length; i++) 
     { 
      body += "<point id='" + this.points[i] + "' />"; 
     } 

     body += "</control>"; 

     return body; 

    } 

    /** 
    * Create new IQ Connection Request 
    * 
    * @param username 
    * @param password 
    */ 
    public IQConnectionRequest(String packetID, String type, String... points) 
    { 
     this.setFrom("[email protected]"); 
     this.setTo("[email protected]/resource"); 
     this.setPacketID(packetID); 
     if (type.toLowerCase().equals("get")) 
      this.setType(IQ.Type.GET); 
     else if (type.toLowerCase().equals("set")) 
      this.setType(IQ.Type.SET); 
     else 
      System.out.println("ERROR: type of " + type + " is not valid. Valid types = SET, GET"); 
    } 

    } 

ListIQProvider:

import org.jivesoftware.smack.packet.IQ; 
import org.jivesoftware.smack.provider.IQProvider; 
import org.xmlpull.v1.XmlPullParser; 

public class ListIQProvider implements IQProvider 
{ 
@Override 
public IQ parseIQ(XmlPullParser parser) throws Exception 
{ 
    ListIQ iq = new ListIQ(); 
    boolean done = false; 

    String val = "", id = "", ts = ""; 
    while (!done) 
    { 
     int eventType = parser.next(); 
     if (eventType == XmlPullParser.START_TAG) 
     { 
      if (parser.getName().equals("point")) 
      { 
       val = parser.getAttributeValue("", "val"); 
       id = parser.getAttributeValue("", "id"); 
       ts = parser.getAttributeValue("", "ts"); 
       iq.addChat(new ListIQ.Chat(val, id, ts)); 
      } 

     } 
     else if (eventType == XmlPullParser.END_TAG) 
     { 
      if (parser.getName().equals("control")) 
      { 
       done = true; 
      } 
     } 
    } 

    return iq; 
} 
} 

ListIQ:

import java.util.ArrayList; 
import java.util.List; 

import org.jivesoftware.smack.packet.IQ; 
public class ListIQ extends IQ 
{ 

private List<Chat> chats; 

public ListIQ() 
{ 
    this.chats = new ArrayList<ListIQ.Chat>(); 
} 

public void addChat(Chat chat) 
{ 
    chats.add(chat); 
} 

public List<Chat> getChats() 
{ 
    return chats; 
} 

@Override 
public String getChildElementXML() 
{ 
    StringBuilder builder = new StringBuilder("<control xmlns=\"http://domain_name.com/powertalk/control/2.0\">"); 
    for (Chat chat : chats) 
    { 
     builder.append(chat.toXml()); 
    } 
    builder.append("</control>"); 
    return builder.toString(); 
} 

public static class Chat 
{ 
    private String id; 
    private String val; 
    private String ts; 

    public Chat(String val, String id, String ts) 
    { 
     this.id = id; 
     this.val = val; 
     this.ts = ts; 
    } 

    public String getID() 
    { 
     return id; 
    } 

    public void setID(String id) 
    { 
     this.id = id; 
    } 

    public String getVal() 
    { 
     return val; 
    } 

    public void setVal(String val) 
    { 
     this.val = val; 
    } 
    public String getTS() 
    { 
     return ts; 
    } 

    public void setTS(String ts) 
    { 
     this.ts = ts; 
    } 

    public String toXml() 
    { 
     StringBuilder builder = new StringBuilder("<point val=\""); 
     builder.append(val).append("\""); 
     builder.append(" id=\""); 
     builder.append(id).append("\""); 
     builder.append(" ts=\""); 
     builder.append(ts); 
     builder.append("\"/>"); 
     return builder.toString(); 
    } 

} 
} 

ServiceProviders:

import org.jivesoftware.smack.provider.ProviderManager; 

public class ServiceProviders 
{ 
    public static void Register_Providers(ProviderManager pm) 
    { 
     pm.addIQProvider("control", "http://domain_name.com/powertalk/control/2.0", new ListIQProvider()); 

    } 
} 
Смежные вопросы