2016-08-30 36 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 ping代码是一个简单的例子,如何发送IQ Ping并监听结果。 – Flow

+0

您是否使用openfire自定义插件进行此通信? – Saveen

+0

从我所了解的ping中,它只是返回true/false。我没有看到从服务器检索IQ结果的方法。你能解释一下我会怎么做,并返回PSI客户端在我上面的例子中所做的结果? – user6776106

回答

0

我放弃了咂嘴4.1.8,我现在用咂嘴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()); 

    } 
}