On presence receiving published item twice ejabberd - xmpp

I am developing a xmpp client and currently working on "pubsub".
I created a node in pubsub and subscribed two users to it.
But when a subscriber login(show presence) i get the last published item twice.
I am using ejabberd server.
Can anyone help??
Thank you.

Same here,
There seems to be two different queues. With notification_type=normal, messages are stored offline. When receiver becomes online, it receives the message twice:
from offline spool, without headline attribute
from pubsub send loop (as node is still configured with send_last_published_item = on_sub_and_presence)
As stated here when configuring pubsub node with notification_type=normal, it's best to disable send_last_published_item or set it to on_sub only in order to avoid receiving the message twice.

Related

Sync data from REST and Websockets

we are building chat application similar to messenger. There is required behavior:
User log in
User should see last N messages, and he should be able to load older messages
New messages should be appended as well
My solution:
I would like to use websockets for this purpose with combination of REST. My idea was that client application decide by message id which messages need. So REST will be used for initial fetching of messages and fetching older messages.
New messages will received by websockets
Possible issue which I should handle:
Application starts subscribing websocket channel for new messages and send request for old messages without initial message id
There is chance that after calling GET request new message come, and will be stored in DB
Client application started subscribing websocket channel so message will received by websockets.
GET request didn't know about this message and fetch last N messages where this new messages will occured and client application will have duplicate record and have to filtered this messages
Can you give me advice if there is some elegant way how to handle this case? Thank you.
I would resolve your task having in mind the following:
The client application should know only about the topic to which to listen. And not the ID of the message starting from which to listen.
It is up to the server to decide what to return (even time should always be tracked server-side).
The WebSocket is used as a transport for STOMP (simply to not reinvent the wheel). The WebSocket connection could be opened once the client application is loaded and not when it is entering the "listen for messages" state. But topic subscription should be performed when necessary.
You can always send GET request and initiate a STOMP subscription simultaneously (almost simultaneously, well with a delay of 1-2 nano-second). And those always should be processed in different promises. But I would align those in the following way: first, the STOMP subscription is initiated, And a specific message on subscription with the initial timestamp of the start of subscription is delivered; second, REST request to get previous 10-100 messages for the TOPIC prior to a specific timestamp (received from STOMP) is performed.
Getting the last 10 messages (which are prior to subscription moment) could be delivered as by REST as by STOMP approach: you can always react to a subscription event on your server-side, and deliver client-specific messages.
Regarding the problem of multiple identical messages from different "data channels", it is easily resolvable: your client (hope that is not jquery, but rather Angular or React or Vue or anything else) will be storing all the data in a single collection in a controller, and filtering and checking by message-id that only unique entries are stored is easy.
BUT if your system will produce hundreds of thousands of messages per second: I guess HTTP-based protocols are not your choice in this case.

How to manage PubSub notifications send while offline in XMPP?

How to get offline message in PubSub? Using the Smack library. after searching I found an answer which looks like this:
// Create a pubsub manager using an existing XMPPConnection
PubSubManager mgr = PubSubManager.getInstanceFor(con);
// Get the node
LeafNode node = mgr.getNode("testNode");
List<? extends Item> items = node.getItems(100);
But node.getItems(100) returns last 100 messages, which can be online and offline too.
1) how to keep track of online and offline message in pubsub using smack?
2) is it possible to get unread message count in pubsub using smack? if yes then how to achieve it?
3) how to know that who(publisher) send this message in a node?
I just went through the documentation of Smack and PubSub from here
and here but didn't find the solutions related to my queries. So can anyone help me to solve this?
1) how to keep track of online and offline message in pubsub using
smack?
I would suggest using the PubSub item ID.
2) is it possible to get unread message count in pubsub using smack?
if yes then how to achieve it?
PubSub nodes don't have a per subscribed unread message count.
If you want to catch-up on all new items since you received the last item from a PubSub node, you'd usually remember the last item's ID and use that to query for all newer items on the PubSub node. Unfortunately there is (currently) no way to query a PubSub node for newer items after a certain ID.
But if you are subscribed to a node, then the service will notify you about new items even if you are offline. And if your server stores those offline messages for you, then you will receive them eventually.
3) how to know that who(publisher) send this message in a node?
Unfortunately there is no reliable way to the the JID of the entity which published an item. This too, could probably be fixed with an extension XEP.

RabbitMQ Structure For Private Messaging

I am currently looking to buildout a messaging service where users can send and receive messages privately between each other. I may have a need for multi-user chat, but for the most part, I only want single recipients to be able to read messages sent to them.
With looking at RabbitMQ, does it make sense to use one exchange, and create a queue for each user when they login and destroy each queue on logout? Are there major performance issues with creating a queue for each user or are there better alternatives?
I am building a REST API and plan on having users send messages to others through an endpoint (/send) and subscribe to their own message streams via websockets or something similar. I will probably store messages in MongoDB as well, so users can access all of their previous messages. Any suggestions on structure are appreciated.
I think your approach is correct. You event don't need an exchange if you will use the default exchange (AMQP Default). And during login create a new queue and keep queue name same as user name. (Just need to make sure user names are unique) And if you publish message to the default exchange with username (ie: queue name) as routing key, RbbitMQ will route that message to that queue only. And on logout if you delete the queue then user is going to miss the messages when he is not online. If it is OK then create queue after login and use the configuration exclusive which says queue gets deleted when there is no consumer. But if you want to keep offline messages then you need to create queue permanently during user signup.

XMPP: count of unread messages

I'm trying to implement chat for my webapp with following features:
When user logs in he should see a number of unread messages (which is both offline messages and "unseen", I will explain "unseen" in next step).
When user is anywhere in the app but on chat window he should be notified that he has a new message. Message should be marked "unseen" and must be added to the count of unread messages.
The first point is quite easily achieved using XEP-0013: Flexible Offline Message Retrieval. So I can retrieve offline messages and when I'm sure user has seen them - I remove them from unread list. But the problem is: how do I achieve same thing for "unseen" messages?
In short what I need is: any message should be marked as offline, unless user sees it and it's removed from the list by explicit request.
Can I achieve that with XMPP and how do I do that?
Thanks in advance.
What you are trying to do is to basically store a counter of unseen stuff in your account. I think you do not need flexible offline retrieval as when you connect the messages would simply become unseen. You thus only have to deal with one case: Unseen.
I will reply from the perspective of ejabberd, that I know better as one of the developer: I would use private storage to store your current state of unseen count and conversation.

GAE channel API chat

Currently im trouble shooting some code that I wrote to create a chat room. I will include the code if necessary but for now I just wanted to hear some possibilities for the problem im having. So basically I have client1 that is listening to a channel and then when clien2 sends a message to the server the message is then sent from the server to all available users. What is happening is that client 2 will send the message and it will be displayed on his browser but client 1 will not receive the message until he refreshes the page or types in a message of his own. So I would think that user presence is being detected fine since the message eventually gets sent to all available users but im not sure? Thoughts?
The Google App Engine blog has a nice case study that talks about how to do this.
They store a list of channel ID's in memcache and send update messages to each of them. They mention that race conditions make memcache not ideal, but it worked well enough for their demo.