Managerul de conexiune

Introducere

Managerul de conexiune este prima piesă a caracteristicilor de chat de grup. Această clasă gestionează conexiunile cu colegii și oferă utilizatorului socket-uri multiplexate la dispozitivele pe care doresc să le conecteze. De exemplu, dacă Alice vrea să fie conectată la unul dintre dispozitivele lui Bob pentru a transfera 2 fișiere, ea va cere ConnectionManager să deschidă 2 canale (unul pe fișier) pentru Bob.

    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
        }
    });

În spatele acestui lucru, ConnectionManager va conecta primul la dispozitivul lui Bob prin DHT (prin ICE) și va configura un TLS Socket. Apoi, va cere un canal, iar când canalul este gata, informează Alice prin intermediul unui callback. Pentru al doilea fișier, va folosi prima socket și va deschide un nou canal (necesită doar 2 pachete TLS, așa că este rapid)

DHT lateral

Este la fel ca call, vezi Exchange ICE candidate, ICE negociere, Encrypt socket de control dar numai în TCP.

Cu toate acestea, atunci când o parte primește o nouă cerere ICE, se declanșează retragerea de apel stabilită de nul onICERequest(onICERequestCallback&&& cb);.

Negocierea unui nou canal

Un canal este definit de un id (unic) și un uri (nu unic). De exemplu (1, «git://*»)

Când este pregătit, ConnectionManager consideră că canalul 0 există. Acest canal se numește canalul CONTROL și este folosit pentru a solicita noi canale.

Protocolul folosit este destul de simplu şi arată ca protocolul RTP:

  1. 16 bits sunt folosite pentru a stoca lungimea corpului.

  2. 16 bits pentru identificarea canalului (destinație)

  3. corp

Deci toate pachetele au un len header de 32 de bituri.

Pentru a solicita un nou canal, ConnectionManager va trimite un obiect ChannelRequest (msgpack este folosit pentru a serializa structul) în canalul 0 pentru a trimite ID-ul și numele noului canal către coleg (cu isAnswer = false).

Închiderea unui canal

O EOF este transmisă pentru un canal dacă lungimea conținutului este de 0.

Structura conexiuniiManager

Proprietatea

  1. Un JamiAccount deține ConnectionManager și are acces la obiecte ChannelSocket (shared_ptr deținut cu MultiplexedSocket.

  2. ConnectionManager deține multiplexedSockets și obiecte ICE

  3. MultiplexedSockets deține transportul TLS și obiectele ChannelSocket

  4. ChannelSocket deţine buferele de date

Rolul

  1. ConnectionManager este utilizat pentru a gestiona conexiunile cu colegii.

  2. MultiplexedSockets sunt utilizate pentru a trimite date prin TLSSocket, a citi pachetele primite și a gestiona canalele.

  3. ChannelSockets sunt folosite de client pentru a interacționa cu celălalt coleg.

Utilizarea

Scenariile sunt descrise în testele unitare corespunzătoare (test/unitTest/connectionManager/connectionManager.cpp)