Then, in the SASL event handler, after successful login I am registering handler for RosterEvent and requesting roster entries:
var rosterModule = halcyon.getModule<RosterModule>(RosterModule.TYPE)!!
halcyon.eventBus.register<RosterEvent>(RosterEvent.TYPE) {
handleRosterEvent(it)
}
rosterModule.rosterGet()
Then, again, in the roter event handler I am attempting to request vCard for each roster item:
fun handleRosterEvent(ev: RosterEvent) {
var nick = if(ev.item.name == null || ev.item.name == "") ev.item.jid.localpart else ev.item.name
if (nick == null || nick == "") nick = ev.item.jid.toString()
val contact = Contact(ev.item.jid.toString(), true, nick)
println("RosterItem added: ${contact.jid}, nickname: '${contact.nickname}'")
// Requesting VCard for the roster item
halcyon.eventBus.register<VCardUpdatedEvent>(VCardUpdatedEvent.TYPE) {
handleVCardEvent(it)
}
var vcardModule = halcyon.getModule<VCardModule>(VCardModule.TYPE)!!
vcardModule.autoRetrieve = true
println("Requesting VCard for ${ev.item.jid}")
vcardModule.retrieveVCard(ev.item.jid)
}
And here is the vCard event handler code:
fun handleVCardEvent(ev: VCardUpdatedEvent) {
println("Received VCard: ${ev.jid.toString()}")
var vCard = ev.vcard
println("VCard: ${vCard.toString()}")
println("VCard nickname: ${vCard?.nickname}")
println("VCard formattedName: ${vCard?.formattedName}")
}
I have about 100 items in the roster which all are received using rosterModule.rosterGet() method call.
Now, the problem is that I request a vCard for each roster item in the roster event handler but I only receive vcard for the last roster item and I receive this vCard for the last roster item 100 times.
It looks like vCard module sends 100 requests but the argument for all these 100 request is set to the last JID requested.
Unknown commented 4 years ago
I can no longer replicate the issue. I did make some changes to the code, nothing too significant though but now I just receive vcard from 1 or 2 roster items out of 100.
Please hold on with investigating this. I am analyzing data and further investigate the problem to provide more reliable description.
Unknown commented 4 years ago
I was able to receive vcards for all roster items but the resulting code I use seems not right.
First I removed eventBus.register call from the handleRosterEvent and moved it to the connection initialization section. This seems be responsible for receiving 100 times call for a single roster item vcard request.
I looked inside the VCardModule to see how to request the vcard and ended up with something like this:
This works but it does not seem right as I do here part of the job which should be done by the library itself. I am creating VCardUpdatedEvent object myself and then pass it to the handler. There is no event firing call which does not follow the library intended API.
Please suggest a better way to request roster item's vcard.
Here is a complete code of the roster item handler.
private fun handleRosterEvent(ev: RosterEvent) {
if (ev is RosterEvent.ItemAdded) {
var nick = if (ev.item.name == null || ev.item.name == "") ev.item.jid.localpart else ev.item.name
if (nick == null || nick == "") nick = ev.item.jid.toString()
val contact = Contact(ev.item.jid.toString(), true, nick)
println("\n\nRosterItem added: ${contact.jid}, nickname: '${contact.nickname}'")
var vcardModule = halcyon.getModule<VCardModule>(VCardModule.TYPE)!!
//vcardModule.autoRetrieve = true
println("Requesting VCard for ${ev.item.jid}")
vcardModule.retrieveVCard(ev.item.jid).response {
handleVCardEvent(VCardUpdatedEvent(ev.item.jid, it.get()))
}.send()
} else {
println("\n\n RosterEvent: ${ev.toString()}")
}
}
Unknown commented 4 years ago
This is correct way to obtain vcard for contact added to roster. The only modification I suggest is better response handling:
First I am logging into the XMPP service.
Then, in the SASL event handler, after successful login I am registering handler for RosterEvent and requesting roster entries:
Then, again, in the roter event handler I am attempting to request vCard for each roster item:
And here is the vCard event handler code:
I have about 100 items in the roster which all are received using
rosterModule.rosterGet()
method call.Now, the problem is that I request a vCard for each roster item in the roster event handler but I only receive vcard for the last roster item and I receive this vCard for the last roster item 100 times.
It looks like vCard module sends 100 requests but the argument for all these 100 request is set to the last JID requested.