jdev - 2021-07-18

  1. hiran

    Hi there. I'm quite new to XMPP and stumble over things that I am not sure how to solve. So I created a java application using the Smack API that can join a MUC and send messages. It can also display the other participants through the presence messages it receives. Now I want to send a message directly to one of the other participants. But if the presence messages are all like <room jid>/<nickname>, how can a message be sent to that participant directly?

  2. flow

    hiran, for non-anonymous rooms you lookup the actual JID of the MUC participant, otherwise you send a private message: https://xmpp.org/extensions/xep-0045.html#privatemessage

  3. hiran

    I think the lookup is the problem. So far the server sends presence messages with these alternative JIDs. How could my client lookup the real user's jid?

  4. hiran

    Ah, what you referred to means I can send a message stanza to the occupant id (which is the <room jid>/<nickname> but it needs to be marked as chat, not as groupchat?

  5. hiran

    And then I guess that message would be send using the MUC rather than the XMPP connection? At least something I have not tried so far...

  6. hiran

    This is a bit strange for me. Here is how my code looke like, and I am alternating the last two lines: MessageBuilder builder = StanzaBuilder.buildMessage(); builder.setBody("Private message..."); builder.to(recipient); builder.ofType(Message.Type.chat); //muc.sendMessage(builder); connection.sendStanza(builder.build()); Now if I use the code as-is (and send the message via the XMPP connection), the message seems to get swallowed. At least I do not see anything on the recipient side. If I use the line before (to send the line via the group chat), another XMPP client (GAIM on Ubuntu 20) displays the message as if it were part of the group chat. I am still confused if I maybe have the right code but interprete the result wrongly?

  7. MattJ

    Is the recipient address a user or a MUC JID?

  8. pep.

    > Ah, what you referred to means I can send a message stanza to the occupant id (which is the <room jid>/<nickname> but it needs to be marked as chat, not as groupchat? If you do that over a MUC don't forget to include <x/> to indicate it's through MUC. Same tag as in the join presence

  9. pep.

    I don't know how to do that in smacks, or if there are helpers

  10. hiran

    Thank you, @pep. I will try to find something

  11. flow

    hiran, what pep said, you need to "builder.addExtension(new MUCUser())"

  12. pep.

    hiran: otherwise you can get the real jid of a participant in their presence, the one sent by the muc during join, or after when they join

  13. hiran

    The x element is not mandatory. According to https://xmpp.org/extensions/xep-0045.html#privatemessage: Note: because this requirement was only added in revision 1.28 of this XEP, receiving entities MUST NOT rely on the existence of the <x/> element on private messages for proper processing.

  14. pep.


  15. pep.

    hiran: it just makes it easier on everybody to distinguish

  16. pep.

    Please do :)

  17. hiran

    No, the presence messages to not contain the real JIDs, only the room JIDs

  18. flow

    hiran, well it explicitly mentions just receiving entities, not sending ones :)

  19. hiran

    I agree I should send the x and I will if I see a chance. Right now I am still seaching how to get Smack to show me what is going on underneath...

  20. flow

    but yes, it may work well without the <x/>. I would still recommend it

  21. flow

    hiran, SmackConfiguration.Debug=true

  22. flow

    hiran, SmackConfiguration.DEBUG=true

  23. hiran


  24. Sam

    "For each extended service discovery information form" does that mean there can be multiple XEP-0128 forms in a single disco#info response? The spec makes it seem like there's only one and I've been operating under that assumption for ages.

  25. Sam

    There's a thing in the revision history that says "now incorrect information" about multiple forms was removed, but not what that is, so maybe there used to be able to be multiple but I still can't tell (or maybe it used to say you only had one and they removed it thinking that would make it clear that there could be multiple, but there aren't)

  26. Link Mauve

    Yes, there can be more than one.

  27. Link Mauve

    For instance, if you want to support both older and newer XEP-0363 clients.

  28. Sam

    Ooh, no, there it is. It's tucked away in the implementation details at the very end. Doesn't mention it anywhere else in the document and definitely nowhere normative where it would make sense.

  29. Sam throws things

  30. Sam


  31. hiran

    Ha! Now, by looking at the debug output I found out that the private message my code is sending does indeed look similar to the message in XEP-045. The x element is still missing. And I was able to see that the server is actually delivering a message where the recipient jid was correctly resolved, and the x was even contained. So now it is more a matter of correctly processing that private message on recipient side, which I should be able to do. And I still need to figure out how to add an x...

  32. Link Mauve

    hiran, flow told you how earlier: 12:36:47 flow> hiran, what pep said, you need to "builder.addExtension(new MUCUser())"

  33. hiran

    Ack. I missed that one before.

  34. hiran

    Confirmed: I do have the x added, just as suggested in the XEP. :-)

  35. hiran

    I also verified if I send the correctly constructed message via the MUC the type gets translated into 'groupchat' which I do not want. So it is important to send private messages via the connection directly. Which kind of makes sense but I was not sure of.

  36. hiran

    So my next goal is to send structured data - not just data that is serialized to a string and sent as message body. How do I best accomplish this via the Smack API? Do I have to introduce a new stanza type (other than Message)? Do I have to go via Extensions, or ...

  37. pep.

    <message> is by design extensible. You don't have to add another stanza type, you can put stuff inside it. <message><foo xmlns='domain.tld:my:ns'>MyData</foo></message>

  38. pep.

    If you need a query/response mechanism you can do the same with IQs

  39. pep.

    (note that you can serialize to XML directly and include it into your private container :))

  40. hiran

    Sounds good. I'd prefer to stick with Messages. So then it is about the content. I guess I do not need to fill the body. But how do I add the custom content?

  41. hiran

    Is the keyword 'Extension'? Then I investigate in that respect...

  42. pep.

    With Smacks I don't know sorry. flow ^

  43. pep.

    Protocol-wise, just see how XEPs are defined, they're just saying "This TAG with this NS can be used to convey X", there's nothing to "declare" in XMPP. Also you only need a XEP (or any kind of public document) if you want other people to use it in the wild

  44. pep.

    Protocol-wise, just see how XEPs are defined, they're just saying "This TAG with this NS can be used to convey X inside a (message|iq|presence)", there's nothing to "declare" in XMPP. Also you only need a XEP (or any kind of public document) if you want other people to use it in the wild

  45. pep.

    If you do want to tell other entities that you support this feature, you may also define a disco feature (to be added to your list of features on your client)

  46. hiran

    Well for now I am creating an XMPP client application that shall be capable of sending message to other clients of that type. It will be a closed system (a game indeed) so I do not think I need to open up the communication and get it standardized. But I need to send structured data - which I theoretically could accomplish by serializing to XML or JSON and put that string into the message body. This would look awkward but for sure work.

  47. pep.

    (say you used 'domain.tld:my:ns' as NS, you can reuse this as a disco feature)

  48. pep.

    Yeah that's not exactly what body is for. It will work for sure but that's not the meaning of this element :)

  49. hiran

    Ah yes, I probably reached the moment where to define that namespace. But even if I had that string (I can make up something) I would not yet know where to put it on Smack

  50. pep.

    I guess the same way as earlier with build.addExtension(new YourExtension())

  51. pep.

    See how MucUser is defined

  52. pep.


  53. hiran

    Ok, then Extension it is. Hmmm, That might be an idea.

  54. hiran

    Strange. I am surfing https://github.com/igniterealtime/Smack/tree/master/smack-core/src/main/java/org/jivesoftware/smack/packet but there is no MUCUser although I am making use of it?

  55. pep.


  56. hiran

    Thanks. smackx indeed

  57. pep.

    (dunno why this is pointing to a specific commit..)

  58. pep.


  59. hiran

    I think that is good enough. i will try to implement a similar pattern. Although the toXML code looks, well it may be normal in the Smack world.

  60. pep.


  61. flow

    toXML() is one of the parts in Smack that has a long history. There may be very well 2 or 3 styles of implementation in XML (if you curious, the older 10-15 year old styles are probably in smack-legacy). These days you want to use the XmlStringBuilder in Smack, which I find very effective in serializing something back to XML (in absence of something like JAXB).

  62. flow

    hiran, ↑

  63. flow

    let me know if you have questions, I am usually around here. but I am probably not for long right now, as we just uncovered our inflatable pool :)

  64. hiran

    Ok, so I managed to get my structured data (so far very simple just a float) into the stanza to be sent. Now, when I receive such a message, on the debug output I can see the correct message is coming in but I fail to parse it. I am trying to call message.getExtension(extensionclass) and message.getExtension(namespace) but for both I get the IllegalStateException: Extension element is not of expected class "XXX", because there is no according extension element provider registered with ProviderManager It seems I am missing one step still. Will try to find the ProviderManager...

  65. hiran

    Ok, seems now I understand where the parsing happens: https://github.com/igniterealtime/Smack/blob/master/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java

  66. hiran

    I am impressed. This really seems to work... Now the only thing I am missing is GAIM tells me that sooo many private messages are still unread, although my custom application already processed them. Is there a way to mark a message as 'read' or 'consumed'?

  67. Martin

    GAIM? 😯

  68. Martin

    When did they rename that to pidgin? 2006?

  69. pep.

    hiran, see chat markers or read receipts, the XEPs

  70. pep.

    What do you mean "consume"?

  71. Martin

    I'd also recommend to use a client from within the last decade.

  72. hiran

    Smack is outdated? Maybe that explains why I am struggling to find up to date documentation. But which client would be more up to date? I am still on Java...

  73. hiran

    With 'consume' I mean to indicate to the server that this message is processed and does not longer have to be queued. It is quite a standard pattern in JMS. Seems like XMPP does not have such components?

  74. Martin

    > Smack is outdated? Maybe that explains why I am struggling to find up to date documentation. I'm talking about GAIM.

  75. hiran

    @pep: I will check read receipts, thank you

  76. hiran

    @Martin: In Ubuntu 20 it is nowhere visible that GAIM should be outdated. Hang on: The windows says Gajim. Is that still outdated=

  77. hiran

    So I am running Gajim 1.1.3 ( https://gajim.org/ )

  78. wurstsalat

    On Ubuntu 20 you'll have an outdated version of Gajim, yes ;) current version is 1.3, and it's actively developed

  79. wurstsalat

    Gajim 1.3 also makes use of read markers, fyi

  80. pep.

    hiran, gajim and gaim are two différent projects, one of which (gaim) renamed (pidgin) around 2006 as Martin said, and is far to be a recommended client nowadays :P

  81. Martin

    > So I am running Gajim 1.1.3 ( https://gajim.org/ ) I'm relieved. 😃

  82. pep.


  83. hiran

    sorry for being sooo nooby. But it seems you guys are having fun! Nevertheless you helped me really quickly. :-)

  84. hiran

    Thank you so much for that

  85. pep.


  86. hiran

    Regarding message receipts: I am having a look at https://xmpp.org/extensions/xep-0184.html It is what I intended, but it also says the sender of a message needs to actively ask for a receipt message. I think this is not my case.

  87. hiran

    I was simply wondering why one XMPP tells me there are 185 unread messages while they were at the same time received and processed by the other client (logged in on the same JID obviously). Is that maybe the normal behaviour and I should completely ignore Gajim?

  88. pep.

    This is not your case as in, you don't want to ask for them?

  89. hiran

    Exactly. The messages sent out by my application do not ask for a receipt. The messages are also received by my application. In parallel they are received by Gajim, and that one tells me to read them all.

  90. hiran

    Would it help to remove the text body so Gajim knows there is nothing for it to display? I will give that a try...

  91. pep.

    Sure yes, if you don't need body, remove it

  92. pep.

    it's not mandatory

  93. hiran

    Looks like removing the message body did silence Gajim. Now that stuff works to my taste. XMPP is really easy to customize. Whoever worked on the design and standardization: Well done!

  94. pep.

    If you ever want to have a peak into the future btw, gajim provides repositories for Debian/Ubuntu :)

  95. pep.


  96. pep.

    Ah they're gone