Project

General

Profile

Multiple Logins and processing the packet

Dathan Pattishall
Added about 4 years ago

So according to this documentation http://docs.tigase.org/tigase-server/5.2.2/dev_guide/html/#How_Packets_are_Processed_by_the_SM_and_Plugins

for every session logged in with the same JID, the plugin will process the packet if a message is sent to that ID.

So If user A communicates with User B and User B is logged in on 3 clients, the plugin will be called 3 times if the chat from user A to user B happens.

My question is, If the plugin already processed the packet how do I tell the plugin to ignore subsequent calls? Any examples of this in the other plugins?


Replies (5)

Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam about 4 years ago

In your example, the plugin will process the packet only once for user B, even if the user B has 3 connections form 3 different clients.

However, if a message from user A is addressed to user's B BareJID, then the message will be delivered to all 3 connections, if the message is addressed to user's B full JID, it will be delivered only to 1 connection.

Added by Dathan Pattishall about 4 years ago

So, how do I tell the plugin to stop processing the message after it already processed it regardless of the number of times tigase wants to process the message due to how many sessions the user has.

Would something like this work

BareJID id = (packet.getStanzaTo() != null) ? packet.getStanzaTo().getBareJID() : null;
        // if the packet is being sent back to the owner
        if (session.isUserId(id) && Message.ELEM_NAME == packet.getElemName()) {

            // ignoring packets resent from c2s for redelivery as processing
            // them would create unnecessary duplication of messages in archive
            if (C2SDeliveryErrorProcessor.isDeliveryError(packet)) {
                return;
            }

            StanzaType type = packet.getType();

            if ((packet.getElement().findChildStaticStr(Message.MESSAGE_BODY_PATH)
                    == null) || ((type != null) && (type != StanzaType.chat) && (type != StanzaType.normal))) {
                log.log(Level.INFO, "Packet is not correct {0}", type);
                return;
            }

            if ((packet.getElemCDataStaticStr(Message.MESSAGE_BODY_PATH) != null)) {
                // save the message
                Packet result = packet.copyElementOnly();
                log.log(Level.INFO, "Storing packet : {0}", result);
                storeMessage(result);

            }
        }
Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam about 4 years ago

You do not need any special logic in your plugin because this is being taken care of on a lower level by SessionManager component.

Added by Luca Stucchi about 4 years ago

Hi Artur,

sorry if I jump into a "closed" discussion, but having more than an active connection is the aspect I am investigating now... and this post seems to describe exactly my need :)

What happens if the same user is connected on different resources on different nodes of a cluster ? Let me make an example, where the user

wizard@oz.consulting

is connected to the first node as

wizard@oz.consulting/office
wizard@oz.consulting/mobile

and to the second node as

wizard@oz.consulting/jacuzzi

Imagine that I am sending a message to the bareJid. It will be delivered to all the connected clients. Once the packet will be sent to all the clients, all of them will independently process it, right ?

If I want that only one of my client will process it, either I send to the fullJid or somehow I let the clients coordinate to process the packet only once, correct ?

I hope I was clear enough to descrive the scenario !

Thanks in advance,

Luca

Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam about 4 years ago

Luca,

Your use-case is valid but whether you use a cluster mode or non-clustered mode is irrelevant. From the client point of view it is all the same and messages are delivered using the same logic (described in RFC). Regardless you use cluster or single server, messages addressed to BareJID will be/should be delivered to all user's connections/resources. A message addresses to FullJID will be/should be delivered to one resource only.

So one of the options, in your case would be to modify Message plugin to send message addressed to BareJID only to one resource/connection based on your custom logic. We used to have logic which sent message to the highest priority resource or to a resource which was active most recently.

    (1-5/5)