Le gestionnaire de connexion
Introduction
Le gestionnaire de connexion est la première partie des fonctionnalités de chat de groupe. Cette classe gère les connexions avec des pairs et offre à l’utilisateur des prises multiplexées à des appareils qu’il souhaite connecter. Par exemple, si Alice veut être connectée à l’un des appareils de Bob pour transférer 2 fichiers, elle demandera au gestionnaire de connexion d’ouvrir 2 canaux (un par fichier) à Bob. Cela donnera:
aliceAccount->connectionManager().connectDevice(bobDeviceId, "file://file1",
[](std::shared_ptr<ChannelSocket> socket) {
if (socket) {
// transfer first file
}
});
aliceAccount->connectionManager().connectDevice(bobDeviceId, "file://file2",
[](std::shared_ptr<ChannelSocket> socket) {
if (socket) {
// transfer second file
}
});
Après cela, le ConnectionManager se connectera d’abord au dispositif de Bob via le DHT (via ICE) et configurera une prise TLS. Ensuite, il demandera un canal, et lorsque le canal sera prêt, informez Alice via un appel-retour. Pour le deuxième fichier, il utilisera la première prise et ouvrira simplement un nouveau canal (il ne nécessite que 2 paquets TLS, donc c’est rapide)
DHT côté
C’est la même chose que call, voir Exchange ICE candidats, ICE négociation, Encrypt le socket de contrôle mais seulement en TCP.
Toutefois, lorsqu’une partie reçoit une nouvelle demande ICE, le retrait de l’appel indiqué par nul onICERequest(onICERequestCallback&&& cb);
est déclenché.
La négociation d’une nouvelle chaîne
Un canal est défini par un id (unique) et un uri (non unique).
Lorsque le ConnectionManager est prêt, il considère que le canal 0 existe. Ce canal est appelé le canal CONTROL et est utilisé pour demander de nouveaux canaux.
Le protocole utilisé est assez simple et ressemble au protocole RTP:
16 bits sont utilisés pour stocker la longueur du corps.
16 bits pour le canal id (destination)
corps
Donc tous les paquets ont un en-tête de 32 bits.
Pour demander un nouveau canal, le ConnectionManager enverra un ChannelRequest
objet (msgpack est utilisé pour sérialiser le struct) dans le canal 0 pour envoyer l’id et le nom du nouveau canal au paire (avec isAnswer = false
). Le paire appellera le callback donné avec ̀ void surChannelRequest(ChannelRequestCallBack&&& cb); et refusera ou acceptera la demande. Si acceptée, le paire répondra avec un ChannelRequest avec les mêmes données (et ̀
isAnswer = true`) et puis les deux pairs seront activés pour informer que le ChannelSock est utilisable.
Fermeture d’un canal
Une EOF est transmise pour un canal si la longueur du contenu est de 0.
Structure de la connexionGestionnaire
Propriété
Un compte Jami possède le ConnectionManager et a accès aux objets ChannelSocket (shared_ptr appartenant au MultiplexedSocket.
Le ConnectionManager possède des objets MultiplexedSockets et ICE
MultiplexedSockets possède le transport TLS et les objets ChannelSocket
ChannelSocket est propriétaire des tampons de données
Rôle
ConnectionManager est utilisé pour gérer les connexions avec les pairs.
MultiplexedSockets sont utilisés pour envoyer des données sur le TLSSocket, lire les paquets entrants et gérer les canaux.
ChannelSockets est utilisé par le client pour interagir avec l’autre paire.
Utilisation
Les scénarios sont décrits dans les tests unitaires correspondants (test/unitTest/connectionManager/connectionManager.cpp
)