Il gestore di connessione
Introduzione
Il gestore di connessione è il primo pezzo delle funzionalità di chat di gruppo. Questa classe gestisce le connessioni con i colleghi e offre all’utente socket multiplexati ai dispositivi che vogliono connettere. Ad esempio, se Alice vuole essere connessa a uno dei dispositivi di Bob per trasferire 2 file, chiederà al gestore di connessione di aprire 2 canali (uno per file) a Bob. Questo darà:
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
}
});
Dietro a ciò, il ConnectionManager prima si connetterà al dispositivo di Bob tramite il DHT (via ICE) e imposterà un TLS Socket. Poi, chiederà un canale, e quando il canale è pronto, informare Alice tramite un callback. Per il secondo file, userà il primo socket e aprirà un nuovo canale (bisogna solo 2 pacchetti TLS, quindi è veloce)
DHT lato
È lo stesso di call, vedere Exchange ICE candidate, ICE negoziazione, Encripta il socket di controllo ma solo in TCP.
Tuttavia, quando una parte riceve una nuova richiesta di ICE, viene attivato il richiamo di ritorno impostato da nul onICERequest(onICERequestCallback&&& cb);
.
Negoziare un nuovo canale
Un canale è definito da un id (unique) e un uri (non unico). ad esempio (1, “git://*”)
Quando è pronto, il ConnectionManager considera che esiste il canale 0 che viene chiamato canale CONTROL e viene utilizzato per richiedere nuovi canali.
Il protocollo utilizzato è piuttosto semplice e assomiglia al protocollo RTP:
16 bit vengono utilizzati per memorizzare la lunghezza del corpo.
16 bit per l’id del canale (destinamento)
corpo
Quindi tutti i pacchetti hanno un len header a 32 bit.
Per richiedere un nuovo canale, il ConnectionManager invierà un ChannelRequest
oggetto (msgpack viene utilizzato per serializzare lo strumento) nel canale 0 per inviare l’id e il nome del nuovo canale al peer (con isAnswer = false
). Il peer richiamerà il callback dato con ̀ void onChannelRequest(ChannelRequestCallBack&& cb); e rifiuterà o accetterà la richiesta. Se accettata, il peer risponderà con un ChannelRequest con gli stessi dati (e ̀
isAnswer = true`) e quindi saranno attivate le richieste di ritorno di entrambi i peer per informare che il ChannelSock è utilizzabile.
Chiudere un canale
Un EOF viene trasmesso per un canale se la lunghezza del contenuto è di 0.
Struttura della connessioneManager
Proprietà
Un account Jami possiede il ConnectionManager e ha accesso agli oggetti ChannelSocket (shared_ptr posseduto con il MultiplexedSocket.
Il ConnectionManager possiede gli oggetti MultiplexedSockets e ICE
MultiplexedSockets possiede il trasporto TLS e gli oggetti ChannelSocket
ChannelSocket possiede i buffer di dati
Ruoli
ConnectionManager è utilizzato per gestire le connessioni con i coetanei.
MultiplexedSockets sono utilizzati per inviare dati tramite il TLSSocket, leggere i pacchetti in arrivo e gestire i canali.
ChannelSockets sono utilizzati dal cliente per interagire con l’altro pari.
Utilizzamento
Gli scenari sono descritti nei corrispondenti test unitari (test/unitTest/connectionManager/connectionManager.cpp
)