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:
16 bits são usados para armazenar o comprimento do corpo.
16 bits para o canal id (destino)
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
Uma JamiAccount possui o ConnectionManager e tem acesso aos objetos ChannelSocket (shared_ptr pertencente ao MultiplexedSocket.
O ConnectionManager possui objetos MultiplexedSockets e ICE
MultiplexedSockets possui o transporte TLS e os objetos ChannelSocket
O ChannelSocket é dono dos buffers de dados
Funções
ConnectionManager é usado para gerenciar conexões com pares.
MultiplexedSockets são usados para enviar dados através do TLSSocket, ler os pacotes recebidos e gerenciar canais.
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
)