-
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?
-
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
-
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?
-
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?
-
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...
-
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?
-
MattJ
Is the recipient address a user or a MUC JID?
-
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
-
pep.
I don't know how to do that in smacks, or if there are helpers
-
hiran
Thank you, @pep. I will try to find something
-
flow
hiran, what pep said, you need to "builder.addExtension(new MUCUser())"
-
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
-
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.
-
pep.
(right?)
-
pep.
hiran: it just makes it easier on everybody to distinguish
-
pep.
Please do :)
-
hiran
No, the presence messages to not contain the real JIDs, only the room JIDs
-
flow
hiran, well it explicitly mentions just receiving entities, not sending ones :)
-
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...
-
flow
but yes, it may work well without the <x/>. I would still recommend it
-
flow
hiran, SmackConfiguration.Debug=true✎ -
flow
hiran, SmackConfiguration.DEBUG=true ✏
-
hiran
:-)
-
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.
-
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)
-
Link Mauve
Yes, there can be more than one.
-
Link Mauve
For instance, if you want to support both older and newer XEP-0363 clients.
-
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.
- Sam throws things
-
Sam
(thanks)
-
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...
-
Link Mauve
hiran, flow told you how earlier: 12:36:47 flow> hiran, what pep said, you need to "builder.addExtension(new MUCUser())"
-
hiran
Ack. I missed that one before.
-
hiran
Confirmed: I do have the x added, just as suggested in the XEP. :-)
-
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.
-
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 ...
-
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>
-
pep.
If you need a query/response mechanism you can do the same with IQs
-
pep.
(note that you can serialize to XML directly and include it into your private container :))
-
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?
-
hiran
Is the keyword 'Extension'? Then I investigate in that respect...
-
pep.
With Smacks I don't know sorry. flow ^
-
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✎ -
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 ✏
-
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)
-
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.
-
pep.
(say you used 'domain.tld:my:ns' as NS, you can reuse this as a disco feature)
-
pep.
Yeah that's not exactly what body is for. It will work for sure but that's not the meaning of this element :)
-
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
-
pep.
I guess the same way as earlier with build.addExtension(new YourExtension())
-
pep.
See how MucUser is defined
-
pep.
builder*
-
hiran
Ok, then Extension it is. Hmmm, That might be an idea.
-
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?
-
pep.
https://github.com/igniterealtime/Smack/blob/3d4e7938a7cc3fa511521702be7688e42a5ff20f/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java
-
hiran
Thanks. smackx indeed
-
pep.
(dunno why this is pointing to a specific commit..)
-
pep.
https://github.com/igniterealtime/Smack/blob/master/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java
-
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.
-
pep.
:)
-
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).
-
flow
hiran, ↑
-
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 :)
-
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...
-
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
-
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'?
-
Martin
GAIM? 😯
-
Martin
When did they rename that to pidgin? 2006?
-
pep.
hiran, see chat markers or read receipts, the XEPs
-
pep.
What do you mean "consume"?
-
Martin
I'd also recommend to use a client from within the last decade.
-
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...
-
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?
-
Martin
> Smack is outdated? Maybe that explains why I am struggling to find up to date documentation. I'm talking about GAIM.
-
hiran
@pep: I will check read receipts, thank you
-
hiran
@Martin: In Ubuntu 20 it is nowhere visible that GAIM should be outdated. Hang on: The windows says Gajim. Is that still outdated=
-
hiran
So I am running Gajim 1.1.3 ( https://gajim.org/ )
-
wurstsalat
On Ubuntu 20 you'll have an outdated version of Gajim, yes ;) current version is 1.3, and it's actively developed
-
wurstsalat
Gajim 1.3 also makes use of read markers, fyi
-
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
-
Martin
> So I am running Gajim 1.1.3 ( https://gajim.org/ ) I'm relieved. 😃
-
pep.
haha
-
hiran
sorry for being sooo nooby. But it seems you guys are having fun! Nevertheless you helped me really quickly. :-)
-
hiran
Thank you so much for that
-
pep.
:)
-
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.
-
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?
-
pep.
This is not your case as in, you don't want to ask for them?
-
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.
-
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...
-
pep.
Sure yes, if you don't need body, remove it
-
pep.
it's not mandatory
-
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!
-
pep.
If you ever want to have a peak into the future btw, gajim provides repositories for Debian/Ubuntu :)
-
pep.
https://gajim.org/download/#nightly-package-from-git-debian-ubuntu
-
pep.
Ah they're gone