jdev - 2021-08-22

  1. MattJ

    flow, smack+websockets question: https://stackoverflow.com/q/68872115/15996

  2. MattJ

    I saw https://github.com/igniterealtime/Smack/pull/399 merged, but I can't see it in a release or docs

  3. MattJ

    and https://download.igniterealtime.org/smack/docs/latest/documentation/ is empty

  4. MattJ

    (linked to from the readme)

  5. MattJ

    and I can't find a changelog

  6. flow

    MattJ, websocket support is not yet in a release (only in pre-releases)

  7. flow

    and thanks for pointing out that latest/documention is empty, will look into it

  8. hiran

    Hi there. It seems my smack client can send messages to a MUC successfully. But as I start and stop my client, more and more accounts get registered on the MUC. This does not look like a problem for me. But interestingly I start receiving messages several times. Sometimes they have the different JIDs, sometime they seem to be for the exactly same JID. How can my client application ensure every message is only received once?

  9. MattJ

    What server software is your account using?

  10. hiran

    I am registered to https://xmpp.libretank.org/ In fact I am writing with that account right now. While I have no clue what that server is running it claims to be 100% compliant...

  11. MattJ

    Recent ejabberd, so it /should/ be correct

  12. MattJ

    You can't join a MUC multiple times from the same full JID, so with a correct server implementation you can only receive multiple messages by having multiple connections open

  13. jonas’

    what are the chances that ejabberd re-routes type="groupchat" sent to a full jid to other domains?

  14. jonas’

    what are the chances that ejabberd re-routes type="groupchat" sent to a full jid to other resources?

  15. jonas’

    what are the chances that ejabberd re-routes type="groupchat" sent to an unavailable full jid to other resources?

  16. jonas’

    no wait, an unavailable full jid shouldn't receive MUC messages anymore

  17. hiran

    stanza sent to <user>@xmpp.libretank.org/10715983031612837986184739 but my connection is for <user>@xmpp.libretank.org/15037136815575938774184803 And I am getting multiple such messages back for one that I send to the MUC

  18. MattJ

    That used to be a bug in some servers, but I've not seen it for a long time. I guess Holger could confirm (but he's not here)

  19. jonas’

    even *if* it was unavailable, then the MUC should remove the user anyway

  20. jonas’

    because unavailable => unavailable presence broadcast => removed from MUC => no messages anymore

  21. jonas’

    and if it isn't unavailable, there's no reason to reroute the messages

  22. MattJ

    Right, but in the case of ghosts the MUC relies on an error bounce from the user's full JID

  23. jonas’

    hiran, is your MUC also with libretank.org?

  24. hiran

    Yes it is

  25. MattJ

    If you are sending unavailable and still receive messages, there is clearly an issue with the MUC

  26. jonas’

    so no s2s problems here

  27. hiran

    The muc address is <room>@muc.xmpp.libretank.org

  28. jonas’

    hiran, do you have by any chance a log of the raw XML exchanged between the server and your client?

  29. jonas’

    of a complete "join muc, send message, receive many" session?

  30. hiran

    I can try to create that

  31. jonas’

    no warranty that it'll help any, but maybe there's something in there which'll help us figure out what's going on

  32. jonas’

    in any case, what you're seeing is not the expected behaviour of a MUC :)

  33. hiran

    I have a log of about 700 lines. How can I best share it with you?

  34. jonas’

    hiran, you could put it on a thing like paste.debian.net

  35. hiran

    Going for pastebin.debian.net...

  36. hiran

    Ok, the log is at https://paste.debian.net/1208577

  37. jonas’

    ugh, smacks logs are so unreadable…

  38. jonas’

    (not your fault :))

  39. jonas’

    hiran, should there be multiple connections in there?

  40. hiran

    No, that client only connects once. However while I develop I am starting, stopping, debbuggin, killing so probably it does not always logoff gracefully.

  41. jonas’

    line 327 is the beginning of a new connection

  42. hiran

    Oh, there is something special I guess. When the player loads a savefile, the nickname gets set to the name from the savegame. I noticed that sending a 'rename' runs into timeouts sometimes. In that case the client will leave the muc and come back as new user. I did not notice that the entire connection is re-established. But the old one would no longer be used in that case, would it?

  43. jonas’

    I don't know

  44. jonas’

    I don't see it being shut down

  45. hiran

    Ok, I can check whether there is a disconnect in my client when it shuts down. But if it crashes that message would not be sent either. The TCP connection is definitely gone.

  46. hiran

    My Gajim client, which is connected to the same muc does not display the other user in the muc chat window. But the roster just increased from hiran (4) to hiran (6)

  47. hiran

    But it seems correct that the server would forward a message sent to the muc to all online users on all online devices/JIDs. With that I could simply filter out those messages that contain the connection's JID as recipient.

  48. hiran

    Unfortunately there seems to be multiple copies of the same message with the correct recipient also. This is confusing me. So how would I efficiently prevent getting a message multiple times or at least filter out the duplicates?

  49. jonas’

    I wonder if you're accidentally sending/receiving via all possibly still established connections at the same time?

  50. jonas’

    the behaviour makes no sense and normally you shouldn't need any filtering like that – to me it sounds as if you accidentally have multiple connections open at this point

  51. hiran

    Even if multiple connections were open (let's assume I do not properly close them and the Smack API keeps them open) my application holds only one reference to a connection and one reference to a muc. It is that one muc that is used to send the message.

  52. jonas’

    maybe you can ask in xmpp:smack@conference.igniterealtime.org?join

  53. hiran

    For the log I sent the message "Hi there". You can find three occurrences. Once it is being sent, twice it is being received.

  54. jonas’

    uhh, but the second reception is from the MUC history on join

  55. jonas’

    and also there are definitely two connections open and active: see lines 603 and 629

  56. hiran

    History? Could make sense. How can I control that? Wither filter those out or prevent them from being sent at all

  57. jonas’

    check the smack API. you have to tell the MUC server on join how much history you want

  58. jonas’

    which you do… (line 634) but the server still gives you history

  59. jonas’

    maybe try maxstanzas='0' instead of seconds='0'…

  60. hiran

    Hehe. Now that explains something. For the two lines/connections: You can see that the nickname changed. <presence to='oolite@muc.xmpp.libretank.org/Jameson/' I believe the /Jameson/ part is the nickname, isn't it? It is allowed for clients to change their nick during a connection?

  61. jonas’


  62. jonas’

    `Jameson/` is the nickname

  63. hiran

    Ok, am fine with that. so it makes sense for the new presence message to be sent.

  64. hiran

    But if the server sends history despite me asking for 0 seconds, I need to filter on the client side.

  65. jonas’

    I think filtering history by seconds is not implemented everywhere

  66. jonas’

    so just see if it helps if you switch to maxstanzas

  67. jonas’

    then you don't have to bother with filtering

  68. jonas’

    (and maxstanzas should be supported everywhere)

  69. hiran

    Ok, I will try that

  70. hiran

    Oh, Smack offers a 'requestNoHistory' method as well

  71. hiran

    Looks much better this way

  72. hiran

    Thank you Jonas, I think now I do not need to filter on client side. :-)

  73. jonas’

    perfect :)

  74. hiran

    I can confirm now that the client did not really close the connection on shutdown. This is fixed, but when I kill the client during a debug session (or it crashes) this will still be the case.

  75. MattJ

    The OS will close your connection for you if the process exits or crashes

  76. Zash

    IFF that's the kind of crash that's referred to

  77. jonas’

    though if you negotiate stream management it may take "a while" before the session is considered dead at the server

  78. MattJ

    True, but you still won't receive messages for those sessions

  79. Zash

    Were it ejabberd that would treat groupchat messages for non-existant sessions the same way as chat messages wrt redirecting to other sessions?

  80. hiran

    When I talk about kill I mean the JVM running my Smack client terminates. For a crash this need not be the case but I terminate it as well. So the process exists, the OS should kill the TCP connection and the server has to live with that.

  81. hiran

    BTW I do neither own nor operate the server so my knowledge about it is fairly limited

  82. MattJ

    Yes, that's totally normal and happens all the time in the real world. In fact the only time streams are closed gracefully is when the user closes the app or logs out. For chat apps that happens rarely.

  83. Zash

    "are" - not sure that's 100% accurate either

  84. Zash

    Dealing in absolutes etc

  85. hiran

    Another question about stanza IDs... From my XML log I can see that every stanza has an id attribute. All but those that my client creates (let's say the payload). Now I am wondering whether those IDs are set by Smack or is it left to me as developer?

  86. hiran

    If the developer is responsible, this call makes sense: message.setStanzaId(chatMessage.msgid); Unfortunately I am using the builder pattern: MessageBuilder builder = StanzaBuilder.buildMessage(); ..... connection.sendStanza(builder.build()); The builder does not allow me to set a message ID, so I'd expect it takes care automatically...?

  87. flow

    hiran, smack will set a stanza id for you, but if I am not mistaken, the builder does also allow you to set one

  88. hiran

    I checked again. And yes, for text messages or muc messages it does. But then I also have custom messages where one player can directly send something to another player. These custom messages seem to not have any ID. So I may be responsible for providing one... <message to='oolite@muc.xmpp.libretank.org/Mogli/Hopeless' from='hiran@xmpp.libretank.org/4802130238238409943552226' type='chat'> <x xmlns='http://jabber.org/protocol/muc#user'> </x> <CommodityParcel xmlns='org.oolite.communicator.parcel' commodity='machinery' amount='1'> </CommodityParcel> </message>

  89. hiran

    There is a builder.getStanzaId() method, but nothing to set the id.

  90. hiran

    Is it possible that only messages typed 'groupchat' do get an ID?

  91. flow

    hiran, you don't need to set an ID if you don't make use of it

  92. flow

    and the fact that you currently work with IDless stanzas makes me believe that you don't need it

  93. hiran

    In case I want to send a response it might make sense to have IDs. Or when else would I need them?

  94. flow

    hiran, message delivery receipts are a prime example

  95. hiran

    Ok, then I will look that up

  96. flow

    hiran> There is a builder.getStanzaId() method, but nothing to set the id. see StanzaBuilder.buildMessage(String stanzaId)

  97. hiran

    No! I did not expect that! LOL

  98. hiran

    Now THAT makes it straightforward again

  99. flow

    hiran, how are those ID-less custom messages constructed?

  100. hiran

    They are constructed like this: MessageBuilder builder = StanzaBuilder.buildMessage(); builder.addExtension(new MUCUser()); builder.to(recipient); builder.ofType(Message.Type.chat); builder.addExtension(new OoliteCommodityParcelExtension(commodity, amount)); connection.sendStanza(builder.build()); // send private message via connection, NOT via muc

  101. hiran

    So yes, I can change the first line and define an ID.

  102. flow

    hiran, you want "XMPPConnection.getSTanzaFactory()", which will set unique IDs for you

  103. flow

    unique per stream that is

  104. hiran

    Oh that would be great already. I will give it a try

  105. hiran

    I just changed the first line into MessageBuilder builder = StanzaBuilder.buildMessage("stanzaID"); and this is what I get in the logs now: <message xml:lang='en-US' to='hiran@xmpp.libretank.org/4168521073172461441552738' from='oolite@muc.xmpp.libretank.org/Mogli/Hopeless' type='chat' id='stanzaID'> <x xmlns='http://jabber.org/protocol/muc#user'/> <CommodityParcel xmlns='org.oolite.communicator.parcel' commodity='liquor_wines' amount='1'/> </message> So setting the ID works. Going for the factory now...

  106. flow

    hiran, so basically, in your example code above, replace 'StanzaBuilder' with 'connection.getStanzaFactory()'

  107. hiran

    It works. First line is now MessageBuilder builder = connection.getStanzaFactory().buildMessageStanza(); and the result <message to='oolite@muc.xmpp.libretank.org/Mogli/Hopeless' from='hiran@xmpp.libretank.org/12184814512061696210552866' id='AWFNU-9' type='chat'> <x xmlns='http://jabber.org/protocol/muc#user'> </x> <CommodityParcel xmlns='org.oolite.communicator.parcel' commodity='textiles' amount='1'> </CommodityParcel> </message>

  108. hiran

    Thank you flow :-)

  109. flow

    hiran, you are welcome