【问题标题】:Smack 4.1 Disable Auto ReceiptsSmack 4.1 禁用自动收据
【发布时间】:2015-05-08 13:04:53
【问题描述】:

我刚刚从折旧的 asmack 切换到 Smack 4.1。 Smack 4.1 会自动发送带有错误 ID 的收据,这在我的情况下会导致异常。

Smack 4.1 在收据上附加了 2 个不同的 ID

这是收到的聊天消息

RECV (0): <message from='***' to='***' xml:lang='en' id='65' kind='0' type='chat'><body>vhh</body><request xmlns='urn:xmpp:receipts'/></message>

这是 Smack 4.1 为响应聊天消息而生成的收到的收据

SENT (0): <message to='***' id='roZ7C-32' type='chat'><received xmlns='urn:xmpp:receipts' id='65'/></message>

Smack 4.1 附加了 2 个不同的 ID,分别是 Received Receipt id='roZ7C-32'id='65'

我的问题是:

  1. 如何使这 2 个 ID 相同
  2. 如何禁用收据以便生成自定义收据

【问题讨论】:

  • 据我所知,Smack 的行为是正确的。如果这导致交货收据接收方出现异常,那么这是一个错误。
  • 为什么 Smack 会针对单个聊天消息附加 2 个不同的 ID 和 Receipt
  • 涉及两个消息节,每个节都有自己的唯一ID。 id 为“65”的第一个消息节被 Smack 确认为与消息节(id“roZ7C-32”)一起发送回包含&lt;received … id='65'/&gt;的“65”的发件人。
  • 我可以让 Smack 发送两个节的 id 65 而不是 roZ7C-32
  • 不,这是不可能的,也不是一个好主意。

标签: android xmpp smack


【解决方案1】:

对于您的第一个问题,要获取已发送消息的 ID,代码将是:

Message ms = new Message();
ms.addBody("EN", Messegeforsend);
DeliveryReceiptRequest.addTo(ms); //tells that you will need delivery for this message
String send_message_id= ms.getStanzaId();

您可以获取已发送消息的 ID,该 ID 与已发送消息的 ID 相同:

deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(connection);
deliveryReceiptManager.addReceiptReceivedListener(new ReceiptReceivedListener() {

            @Override
            public void onReceiptReceived(String arg0, String arg1, String arg2,Stanza arg3) {
                String delivered_message_id = arg2;
}

});

send_message_id 将完全等于delivered_message_id,所以你会知道哪条消息已经被传递了

【讨论】:

    【解决方案2】:

    SMACK 4.1.0 消息接收监听器写在下面的代码

    try {
                    Message ms = new Message();
                    ms.addBody("EN", "deleriyed");
                    ms.setTo(message.getFrom());
                    ms.setStanzaId(message.getStanzaId());
                    DeliveryReceiptRequest.addTo(ms);
                    connection.sendStanza(ms);
                } catch (NotConnectedException e) {
                    e.printStackTrace();
                }
    

    【讨论】:

      【解决方案3】:

      您可以禁用此功能的方法是在发送消息时不添加回执:

      最重要的方法是

      处理包扩展

      //Creating message in your method
      public sendMessage(Jid to, String body){
          Message msg = Message(to, body);
          //Create and save your deliveryID to SQLite database
          deliveryID = DeliveryReceiptRequest.addTo(msg);
          ChatManager.getInstanceFor(connection).chatWith(jid).send(msg);
      }
      
      //Declare your stanza listener
      private MessagePacketListener messagePacketListener;
      //In your cotnructor   
      messagePacketListener = new MessagePacketListener(context);
      
      //Then in your login method register your stanza listener like this
      public void login() throws SmackInvocationException, XmppStringprepException {
              connect();
              try {
                  if (!con.isAuthenticated()) {
                      ....
                      con.addSyncStanzaListener(messagePacketListener, new StanzaTypeFilter(Message.class));
                      ....
                      }
              } catch(Exception e) {
                          ....
                  }
              }
      
      
      
      //Your StanzaListener where you parse your incoming message and if it is without body it is Delivery receipt
      //Now you have your MessagePacketListener that process the incoming messages
      
      public class MessagePacketListener implements StanzaListener{
          private Context context;
      
          MessagePacketListener(Context context) {
              this.context = context;
          }    
          @Override
          public void processStanza(Stanza packet) {
              Message msg = (Message)packet;
      
              //Message that have body
              if(msg.getBodies().size() > 0){
                  //Text message
                  //Do something with message msg.getBody()
              }
              else{
                  //This must be sth like delivery receipt or Chat state msg and get your deliveryID
                  processPacketExtension(msg);
              }
          }
      
          //processPacketExtension method that receive packet delivery ectension
          private void processPacketExtension(Message msg) {
              Collection<ExtensionElement> extensions = msg.getExtensions();
              if (extensions != null) {
                  Iterator<ExtensionElement> iterator = extensions.iterator();
                  if (iterator.hasNext()) {
                      ExtensionElement extension = iterator.next();                
                      if(extension instanceof DeliveryReceipt){
                          //Do sth with deliveryID
                          String deliveryID = ((DeliveryReceipt) extension).getId();
                      }
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-07
        • 2012-10-05
        • 1970-01-01
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-28
        相关资源
        最近更新 更多