Na semana passada, eu estava falando em WebCamp Zagrebuma ótima conferência para desenvolvedores e designers. Fiz uma apresentação intitulada 'Let your devices talk to each other' (Deixe seus dispositivos conversarem entre si). Para a parte de demonstração, criei um aplicativo de mensagens muito simples que sincroniza automaticamente com qualquer outra pessoa que o esteja executando na mesma rede. Os slides e o código de demonstração estão em github. A apresentação foi filmada e deverá estar on-line em breve.
O tópico desta apresentação é IoT (Internet das Coisas), M2M (Máquina a máquina) e descentralização. Todas essas coisas da Internet geralmente enviam seus dados (na maioria das vezes, dados muito privados, sim, estou olhando para você, movimento Quantified Self) para um servidor em algum lugar na nuvem. Isso basicamente significa que os dados não são mais seus (privados). Isso é muito triste. Essa é a principal ideia que me levou a fazer esta palestra. Mas há muitos outros bons motivos para permitir que seus dispositivos conversem entre si. E isso não é uma coisa nova. O que chamamos de M2M agora é muito comum no setor há anos.
Mas vamos voltar ao tópico original. Uma maneira de evitar essa centralização seria que suas coisas da Internet deixassem de ser coisas da Internet e começassem a ser coisas da sua rede doméstica. Eles deveriam começar a se comunicar uns com os outros e enviar os dados para onde você decidir, como uma instância do Couchbase Lite em execução em um RaspberryPI ou qualquer outro dispositivo pequeno com suporte à JVM.
E, é claro, uma maneira de fazer com que os dispositivos se comuniquem entre si pode ser instalar o Couchbase Lite neles e usar a sincronização P2P. Já temos o vários postagem no blog sobre o assunto. Portanto, para trazer algo novo a esse assunto, vou lhe dizer como tornar essa sincronização automática.
A sincronização é baseada em links de replicação. Eles geralmente exigem um endereço e credenciais. Como quero ter o mínimo de atrito possível, pulei a parte de credenciais/segurança. Isso é ruim, mas facilitou muito a demonstração da minha apresentação. Portanto, se tudo o que você precisa é de um endereço, como obtê-lo automaticamente?
Para que a sincronização P2P funcione, os dispositivos sincronizados precisam estar na mesma rede. E a boa notícia é que existem vários protocolos de rede para fazer a descoberta automática de serviços. Você já deve ter ouvido falar de coisas como Bonjour, RendezVous, ZeroConf, Android NSD, mDNS, DLNA, UPnP e outros. A maioria delas é baseada no registro de serviços DNS. Porque sim, o DNS pode fazer mais do que mapear IPs para hosts. Ele também pode armazenar uma lista de serviços com seu endereço, nome e descrição.
É isso que estou usando em minha demonstração. Escolhi uma implementação Java simples com base no Biblioteca JmDNS. Dessa forma, tenho quase o mesmo implante em meu aplicativo nativo Java e no Android. Ele funciona por meio de transmissão UDP. Ele envia pacotes para outras coisas conectadas na rede
Aqui está uma breve olhada nos trechos de código mais relevantes.
Iniciar o Couchbase Lite Listener no dispositivo para torná-lo capaz de receber conexões.
1 2 3 4 5 6 7 8 9 |
público int startCBLiteListener(int porto) { LiteListener ls = novo LiteListener(banco de dados.getManager(), porto, nulo); Tópico linha = novo Tópico(ls); linha.iniciar(); retorno ls.getListenPort(); } |
Expondo um novo serviço usando JmDNS
1 2 3 4 5 6 |
público vazio exposeService(int porto) lançamentos IOException { ServiceInfo sInfos = ServiceInfo.criar(TIPO DE SERVIÇO, serviceName, porto, SERVICE_DESCRIPTION); jmdns.registerService(sInfos); } |
Escutar um serviço específico usando JmDNS. O ouvinte DiscoveryListener é importante porque é onde você pode realmente configurar a sincronização.
1 2 3 4 5 |
público vazio listenForService(){ jmdns.addServiceListener(TIPO DE SERVIÇO, novo Ouvinte de descoberta(banco de dados, jmdns, serviceName)); } |
Essa não é a implementação mais limpa que existe, mas você entenderá a ideia. Dê uma olhada especial no método serviceResolved. É ele que é chamado quando um novo serviço é descoberto na rede. Ele nos fornece o URL do serviço, o que nos permite configurar o link de replicação clássico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
pacote org.couchbase.desenvolver; importação com.couchbase.leve.Banco de dados; importação com.couchbase.leve.ouvinte.LiteListener; importação com.couchbase.leve.replicador.Replicação; importação javax.jmdns.JmDNS; importação javax.jmdns.ServiceEvent; importação javax.jmdns.Listador de serviço; importação java.io.IOException; importação java.rede.URL; /** * Criado por ldoguin em 13/02/15. */ público classe Ouvinte de descoberta implementa Listador de serviço { privado Banco de dados banco de dados; privado JmDNS jmdns; privado Cordas serviceName; público Ouvinte de descoberta(Banco de dados banco de dados, JmDNS jmdns, Cordas serviceName) { este.banco de dados = banco de dados; este.jmdns = jmdns; este.serviceName = serviceName; } @Substituir público vazio serviceAdded(ServiceEvent evento) { se (! serviceName.iguais(evento.getName())){ jmdns.requestServiceInfo(evento.getType(), evento.getName(), 10); } } @Substituir público vazio serviceRemoved(ServiceEvent evento) { Sistema.fora.println(evento.getName() + " removido"); } @Substituir público vazio serviceResolved(ServiceEvent evento) { Sistema.fora.println("RESOLVIDO"); Cordas[] serviceUrls = evento.getInfo().getURLs(); para (Cordas url : serviceUrls) { Sistema.fora.println(url); setupSync(banco de dados, url + "/messages"); } } público vazio setupSync(Banco de dados banco de dados, Cordas syncUrl) { tentar { URL url = novo URL(syncUrl); Replicação pullReplication = banco de dados.createPullReplication(url); pullReplication.setContinuous(verdadeiro); pullReplication.iniciar(); Replicação pushReplication = banco de dados.createPushReplication(url); pushReplication.setContinuous(verdadeiro); pushReplication.iniciar(); } captura (IOException e){ lançar novo Exceção de tempo de execução(e); } } } |
E esse é um projeto experimental divertido, fácil de implementar, para garantir que todos os seus dispositivos Couchbase Lite possam se sincronizar facilmente. É claro que há muito mais que pode ser feito. Como adicionar a parte de segurança. Você poderia imaginar uma primeira sincronização manual que trocasse as credenciais uma vez e depois fizesse todo o resto automaticamente. Espero que você ache isso útil. Não hesite em comentar e nos dar seu feedback!