-
MattJ
flow, smack+websockets question: https://stackoverflow.com/q/68872115/15996
-
MattJ
I saw https://github.com/igniterealtime/Smack/pull/399 merged, but I can't see it in a release or docs
-
MattJ
and https://download.igniterealtime.org/smack/docs/latest/documentation/ is empty
-
MattJ
(linked to from the readme)
-
MattJ
and I can't find a changelog
-
flow
MattJ, websocket support is not yet in a release (only in pre-releases)
-
flow
and thanks for pointing out that latest/documention is empty, will look into it
-
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?
-
MattJ
What server software is your account using?
-
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...
-
MattJ
Recent ejabberd, so it /should/ be correct
-
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
-
jonas’
what are the chances that ejabberd re-routes type="groupchat" sent to a full jid to other domains?✎ -
jonas’
what are the chances that ejabberd re-routes type="groupchat" sent to a full jid to other resources? ✏
-
jonas’
what are the chances that ejabberd re-routes type="groupchat" sent to an unavailable full jid to other resources? ✏
-
jonas’
no wait, an unavailable full jid shouldn't receive MUC messages anymore
-
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
-
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)
-
jonas’
even *if* it was unavailable, then the MUC should remove the user anyway
-
jonas’
because unavailable => unavailable presence broadcast => removed from MUC => no messages anymore
-
jonas’
and if it isn't unavailable, there's no reason to reroute the messages
-
MattJ
Right, but in the case of ghosts the MUC relies on an error bounce from the user's full JID
-
jonas’
hiran, is your MUC also with libretank.org?
-
hiran
Yes it is
-
MattJ
If you are sending unavailable and still receive messages, there is clearly an issue with the MUC
-
jonas’
so no s2s problems here
-
hiran
The muc address is <room>@muc.xmpp.libretank.org
-
jonas’
hiran, do you have by any chance a log of the raw XML exchanged between the server and your client?
-
jonas’
of a complete "join muc, send message, receive many" session?
-
hiran
I can try to create that
-
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
-
jonas’
in any case, what you're seeing is not the expected behaviour of a MUC :)
-
hiran
I have a log of about 700 lines. How can I best share it with you?
-
jonas’
hiran, you could put it on a thing like paste.debian.net
-
hiran
Going for pastebin.debian.net...
-
hiran
Ok, the log is at https://paste.debian.net/1208577
-
jonas’
ugh, smacks logs are so unreadable…
-
jonas’
(not your fault :))
-
jonas’
hiran, should there be multiple connections in there?
-
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.
-
jonas’
line 327 is the beginning of a new connection
-
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?
-
jonas’
I don't know
-
jonas’
I don't see it being shut down
-
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.
-
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)
-
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.
-
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?
-
jonas’
I wonder if you're accidentally sending/receiving via all possibly still established connections at the same time?
-
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
-
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.
-
jonas’
maybe you can ask in xmpp:smack@conference.igniterealtime.org?join
-
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.
-
jonas’
uhh, but the second reception is from the MUC history on join
-
jonas’
and also there are definitely two connections open and active: see lines 603 and 629
-
hiran
History? Could make sense. How can I control that? Wither filter those out or prevent them from being sent at all
-
jonas’
check the smack API. you have to tell the MUC server on join how much history you want
-
jonas’
which you do… (line 634) but the server still gives you history
-
jonas’
maybe try maxstanzas='0' instead of seconds='0'…
-
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?
-
jonas’
yes
-
jonas’
`Jameson/` is the nickname
-
hiran
Ok, am fine with that. so it makes sense for the new presence message to be sent.
-
hiran
But if the server sends history despite me asking for 0 seconds, I need to filter on the client side.
-
jonas’
I think filtering history by seconds is not implemented everywhere
-
jonas’
so just see if it helps if you switch to maxstanzas
-
jonas’
then you don't have to bother with filtering
-
jonas’
(and maxstanzas should be supported everywhere)
-
hiran
Ok, I will try that
-
hiran
Oh, Smack offers a 'requestNoHistory' method as well
-
hiran
Looks much better this way
-
hiran
Thank you Jonas, I think now I do not need to filter on client side. :-)
-
jonas’
perfect :)
-
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.
-
MattJ
The OS will close your connection for you if the process exits or crashes
-
Zash
IFF that's the kind of crash that's referred to
-
jonas’
though if you negotiate stream management it may take "a while" before the session is considered dead at the server
-
MattJ
True, but you still won't receive messages for those sessions
-
Zash
Were it ejabberd that would treat groupchat messages for non-existant sessions the same way as chat messages wrt redirecting to other sessions?
-
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.
-
hiran
BTW I do neither own nor operate the server so my knowledge about it is fairly limited
-
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.
-
Zash
"are" - not sure that's 100% accurate either
-
Zash
Dealing in absolutes etc
-
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?
-
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...?
-
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
-
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>
-
hiran
There is a builder.getStanzaId() method, but nothing to set the id.
-
hiran
Is it possible that only messages typed 'groupchat' do get an ID?
-
flow
hiran, you don't need to set an ID if you don't make use of it
-
flow
and the fact that you currently work with IDless stanzas makes me believe that you don't need it
-
hiran
In case I want to send a response it might make sense to have IDs. Or when else would I need them?
-
flow
hiran, message delivery receipts are a prime example
-
hiran
Ok, then I will look that up
-
flow
hiran> There is a builder.getStanzaId() method, but nothing to set the id. see StanzaBuilder.buildMessage(String stanzaId)
-
hiran
No! I did not expect that! LOL
-
hiran
Now THAT makes it straightforward again
-
flow
hiran, how are those ID-less custom messages constructed?
-
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
-
hiran
So yes, I can change the first line and define an ID.
-
flow
hiran, you want "XMPPConnection.getSTanzaFactory()", which will set unique IDs for you
-
flow
unique per stream that is
-
hiran
Oh that would be great already. I will give it a try
-
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...
-
flow
hiran, so basically, in your example code above, replace 'StanzaBuilder' with 'connection.getStanzaFactory()'
-
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>
-
hiran
Thank you flow :-)
-
flow
hiran, you are welcome