O gerente de ligação

Introdução

O gerente de conexão é a primeira peça das funcionalidades de bate-papo de grupo. Esta classe gerencia conexões com pares e oferece ao usuário soquetes multiplexados para dispositivos que desejam conectar. Por exemplo, se Alice quiser ser conectada a um dos dispositivos de Bob para transferir 2 arquivos, ela pedirá ao ConnectionManager que abra 2 canais (um por arquivo) para Bob. Isso 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
        }
    });

Por trás disso, o ConnectionManager primeiro se conectará ao dispositivo de Bob através do DHT (via ICE) e configurará um TLS Socket. Em seguida, ele pedirá um canal, e quando o canal estiver pronto, informe Alice através de um callback. Para o segundo arquivo, ele usará o primeiro socket e abrirá um novo canal (apenas precisa de 2 pacotes TLS, então é rápido)

Lado DHT

É o mesmo que Chamadas, consulte Exchange ICE candidates, ICE negotiation, Encrypt the control socket, mas somente em TCP.

No entanto, quando uma parte recebe um novo pedido do ICE, a chamada de volta definida por ` nulo onICERequest(onICERequestCallback&&& cb);

Negociar um novo canal

Um canal é definido por um id (exclusivo) e um uri (não exclusivo). Por exemplo, (1, ‘git://*’)

Quando está pronto, o ConnectionManager considera que o canal 0 existe.

O protocolo usado é bastante simples e parece o protocolo RTP:

  1. 16 bits são usados para armazenar o comprimento do corpo.

  2. 16 bits para o canal id (destino)

  3. corpo

Todos os pacotes têm um lenheader de 32 bits.

Para solicitar um novo canal, o ConnectionManager enviará um objeto ChannelRequest (msgpack é usado para serializar o estruto) no canal 0 para enviar o id e o nome do novo canal para o peer (com isAnswer = false). O peer chamará o callback dado com ̀ void onChannelRequest(ChannelRequestCallBack&&& cb); e recusará ou aceitará o pedido. Se aceito, o peer responderá com um ChannelRequest com os mesmos dados (e ̀isAnswer = true`) e então ambos os peers serão activados para informar que o ChannelSock é utilizável.

Fechar um canal

Uma EOF é transmitida para um canal se o comprimento do conteúdo for 0.

Estrutura da conexãoGestor

Propriedade

  1. Uma JamiAccount possui o ConnectionManager e tem acesso aos objetos ChannelSocket (shared_ptr pertencente ao MultiplexedSocket.

  2. O ConnectionManager possui objetos MultiplexedSockets e ICE

  3. MultiplexedSockets possui o transporte TLS e os objetos ChannelSocket

  4. O ChannelSocket é dono dos buffers de dados

Funções

  1. ConnectionManager é usado para gerenciar conexões com pares.

  2. MultiplexedSockets são usados para enviar dados através do TLSSocket, ler os pacotes recebidos e gerenciar canais.

  3. ChannelSockets são usados pelo cliente para interagir com o outro colega.

Utilização

Os cenários são descritos nos testes unitários correspondentes (test/unitTest/connectionManager/connectionManager.cpp)