Synchronizing roster with the jabber server while user is offline - xmpp

I am using ejabbered with converse.js and I am playing around with user administration on ejabberd admin panel, more precisely with adding/removing a user from and to a shared group.
While the user is online(converse client is connected to the server) any changes I do in admin panel are reflected in the client immediately. When I add or remove user to and from a group, contacts are updated appropriately. I can also see the roster add/remove messages in the websocket connection as I submit changes in the admin panel.
While user is offline(converse client is not connected) and I add the user to the new shared group, next time user connects, he will see the updated contact list(new contacts are added on the client), BUT if I remove the user from a shared group while he is offline, next time he comes online, the roster will not be changed. Even if I click the contacts refresh button, no contact will be removed.
In order words, only roster additions are respected while user is offline.
Now I kinda understand what's going on, since "remove" message is essentially missed by the client, but I am still wondering, is there any way to synchronize roster items between conversejs and ejabberd in such a way that they are 1 to 1 even while user is offline?

I can reproduce that problem using ejabberd from git and Converse 9.1.0. It seems Converse stores the roster in the webbrowser, and restores it at login, probably to save network consumption.
I disabled this option in Converse, and now the roster is requested at every login:
https://conversejs.org/docs/html/configuration.html#clear-cache-on-logout
Offtopic: during the last weeks, I've added some improvements to administer mod_conversejs, see
https://github.com/processone/ejabberd/commits/master/src/mod_conversejs.erl

Related

How do I get GraphQL to get live/new data from database without polling?

I have a backend running GraphQL, MongoDB + Mongoose, and Apollo. This application has functionality for user accounts and a friends list. Each user can login to their account and see a list of friends with their current 'status'; If a friend changes their status, I need that change to be reflected on the user's side. An example of this is like facebook's "green dot" on messenger that tells you when one of your friends is online using the application.
I have been searching documentation for GraphQL and have been suggested either Subscriptions or Live Queries. Subscriptions seem to be the majority of suggestions from what I understand, live queries are not officially part of GraphQL or were dropped.
Does anyone have a solution to getting "live" data with GraphQL/MongoDB that doesn't involve polling for this scenario?
You already seem to have your answer: subscriptions!
Using your example, consider two users - mikep17 and mcy. You are mikep17, logged into your application and viewing your list of friends and their statuses. I am your friend, and I log in as you are viewing this list, and you want to see that in your application's UI.
On the frontend, in your application's instance, your application will execute a subscription to some event. Let's call it friendStatusChange. Now your application is "listening" for that event in order to respond accordingly. Let's assume that when your application receives the event, it can parse out the information that "I" (mcy) have changed from offline => online and then use that to add the "green dot" next to my username.
On the backend, your GraphQL server will have code that handles your user functionality - logging in, logging out, etc. It will need to be enhanced to hook into these actions and "publish" the friendStatusChange event as applicable.
Now, instead of your client constantly asking (polling) "did a friend's status change? how about now? now?", it can just listen and wait for your server to tap it on the shoulder and say "hey buddy, your friend mcy's status changed".

MAM XEP-0313 - Query conversation list for a particular user

I am developing a mobile messaging app (ios) and I support the logout feature. I want to keep the latest conversation list when the users logs in back again. Because the local storage of the app gets cleaned once logout.
I am using MAM XEP-0313 sucessfully but I have not found an IQ to query the conversation list of a particular user.
For example:
chat
user_a -> user_b
user_c
user_d
user_f
user_a has had conversations with 4 users and he wants to logout of the app, when he comes back in he needs to get those last 4 conversation threads on his list.
What I do when a user messages another user is that I add them to my roster and have the logic of automatic subscription. So I was thinking to use the roster history logic to query this collection but I was also expecting the MAM module to have a more direct way..
I am using MongooseIM server
I understand your problem, the solution you have is probably the best one you can have with standard XEPs and their implementations.
The conversation list is actually sth missing in MAM spec or in general in XMPP. There are some works to define an extension to get you all the conversations where you have some unread messages (so called "unread sync"). Will this be enough for you or you would rather want to get some kind of "inbox". By "inbox" I mean a list of all recent conversations with unread messages count where there are some unread messages.

How to send notifications to an offline member deleted from a chat group?

I am new to XMPP and working on a group chat application similar to watsapp. The scenario is:
"User A creates a group chat adding users B, C and D to it. All members are online and they are chatting. Now D takes the app to background or kills the app. Now A removes D from the group. How user D will be notified that A has removed him from the group, when D comes back to the app ?
I am using ejabberd (15.11) with PostgreSQL and following the XMPP architecture. I am not sure if the answer is out there, so would like to get help here.
XMPP MUC specifications says in section 9.5: Modifying the Member List:
If a removed member is currently in a members-only room, the service
SHOULD kick the occupant by changing the removed member's role to
"none" and send appropriate presence to the removed member as
previously described. The service MUST subsequently refuse entry to
the user.
It means that the participant will only receive his own status change modification if it is present it the room when the event happen. If he is not online at that time, he can only know his credentials has been removed, because he cannot join the room anymore. In other words, in the current state of the specifications, there is no way to get that removal notification when user was not in the room when the removal happened. You can just infer he was removed because he cannot join the room again on next login.
There is nothing else defined in XEP-0045 Multi-User Chat to store membership event for offline participant and later delivery.

Where does openfire store roster values except the database?

I am implementing xmpp chat server with openfire and mysql. Openfire does create a lot of tables in the db. It has roster table but only adding rows there doesn't creates roster where as adding rows in the user table creates the user and I am able to login with the user. So my question is does openfire stores the rosters anywhere else because if I delete the entries from the roster table it still shows previous roster.
Deleting roster does reflect on the roster but it will take some time as openfire store cache. If you go to Server manager->cache summary you can see the list of cache. Just delete the Roster cache, you can see that roseters are same as it is in the database. i don't think openfire store roster values anywhere else. And if you add/delete roster do it with User service plugin or make your own plugin with java don't just delete/update it on database.
It likely caches the roster in memory. If you were to stop the server, make the database change, then start the server, you might see the changes reflected. That doesn't work well in practice, so you may need to use protocol to change the roster.

Server managed roster in Tigase

Generally in messenger services, user adds or deletes contacts and let knows server about it. Server then takes necessary actions.
However, our requirement is "server decides contacts list, makes roster changes accordingly and clients receives updates about the same". How can we achieve this in Tigase?
There is a dedicated API in the Tigase just for that. It is called a DynamicRoster. Maybe the name is the most accurate. Dynamic because it is managed by the server and it can change any time user requests the roster.
Anyway, there are code examples in the Tigase main code repository. You can have multiple dynamic rosters active at the same time and they can retrieve contacts from different locations.
There is also a roster protocol extension which allows you to keep extra information for the contacts in the dynamic roster such as phone numbers, etc... More info about this o the Tigase.org website in the devel guide section.
Hope this helps.