RetroShare has a system for decentralized chat called the "chat lobbies".
The image below represents a group of connected friends. The peers in yellow (A,B,C,H,I and J) are subscribed to a chat lobby. Each peer of this group is receiving all messages of every other peer in this group.
Messages are relayed by peers subscribed to this lobby only along the red connections. This concept allows to have two types of lobbies:
- public lobbies: Public lobbies are advertised to friends, and friends can join them by double-clicking on the lobby. A chat window appears and the user can participate in the lobby. The image below shows an example of a lobby list advertised by direct friends:
- private lobbies: Private lobbies are not advertised to friends. They require a peer to be explicitly invited to a lobby to be able to access it. That makes the private lobbies totally impossible to spy on from outside the lobby, including direct friends who are not yet in the lobby.
Inside libretroshare, a lobby object cache contains the IDs of lobby objects that have been seen in the last 20 minutes, to only show and forward each of them once.
New RsItems have been designed:
- lobby management items. Such items are sent to friends to manage lobbies. Typically invitations, advertisement of lobby lists, etc.
- lobby object items. These items all derive from the same class that make them broadcast-able through a lobby. A routine function forwards items to other friends in the lobby and updates the lobby object cache.
For each peer, a chat lobby is just another virtual peer to chat to, just as in normal private chat. The GUI side of RetroShare therefore makes little difference between a chat lobby and a friend to talk to.
Lobby connection challenges
Every 20 messages, the lobby tries to add new connections: if two peers are subscribed to the same lobby, but not registered as direct participants, they make known to each other that they can forward messages directly. This is done in a way that prevents unwanted peers to spy on a lobby, using a system of connection challenge:
Peer B and C have roughly the same lobby message IDs, since they are subscribed to a common lobby, without actually knowing it. Peer C computes a non reversible hash from
- the lobby ID
- one of the recent message IDs of this lobby,
- B's SSL id,
and sends this hash into a connection challenge packet to B (C repeats the operation for all his friends, but the hash will be different)
B receives a connection challenge with code c. It tries all possible combinations of known lobby ID and lobby messages ID in cache. If a match is found, B knows that C participates in the matching lobby, and sends back an invitation to C to join the lobby. C receives the invitation and directly connects B (without GUI notice).
This protocol ensures that if C knows nothing about the lobby B tries to challenge, he cannot find out what the ID of this lobby actually is.
If a peer unsubscribes from a lobby, he can be responsible for splitting the lobby into two separated components. The connection challenges help preventing that, but this situation can still happen. Once disconnected, the lobby will be able to reconnect using challenges for a limited time period (while caches from both sides still share some message IDs). After that, the lobby can be connected manually by inviting a friend on the other side.
Lobbies with a very large number of people will probably not be able to propagate messages from end to end. While there is QoS on the leaving side of the packet transmission, there's no QoS on the incoming side. This means that if a peer is performing heavy file transfer for instance, it might slow down lobby traffic significantly. Across multiple hops, it's possible that messages take more time to travel than what the lobby cache can handle.
Chat lobbies are volatile objects. They are not saved. If a large number of persons is using a lobby, there is very little chance that the lobby will eventually disappear. On the contrary, a lobby that nobody uses will disappear by itself. This strategy promotes active lobbies.
Original functionality requirements list (moved from Groups)
- we could call that 'conversation lobby'
- in the gui, one clicks on a group and asks 'start lobby'. An invitation is sent to all participants of the group.
- the gui displays a list of nearby group chats the user is invited to, and allows participation to them
- for each lobby, a chat window appears, with the names of the participants (basically who sent messages) and collects messages from the user.
- invitations are sent to direct friends only
- we need a lobby service to broadcast and relay messages, and notify the GUI.
- each lobby has an id, that identifies messages to belong to this lobby. Appart from that, messages have a time stamp used for sorting/display them, and a peer name (not an id) of who posted the msg.
- each node knows the list of his direct friends who participate in the conversation
- when chatting in a group, messages to friends which will relay them to the entire group, using a cache system to avoid duplicates, and insert messages in the correct order.
- The msg broadcasting must only use people participating in the conversation to relay messages, to prevent evesdropping.
- the lobby finishes when all peers have disconnected. A big lobby can split into separate ones because of connexion issues. Do we cache messages and re-send them as the connexion re-establishes? Possibly. On the point of view of the user, the lobby exists while participating friends are connected and haven't sent a "lobby disconnect" packet. Such a packet is sent when the user closes the lobby window.
|This page is part of RetroShare Documentation|
|Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.|