O padrão Publisher-Subscriber sempre me despertou interesse pela sua arquitetura limpa e pela independência dos componentes que compõem este padrão. Nas leituras que busco na internet sobre o tema, me deparei com a Nearby Messages API do developers.google. Sua descrição, que pode ser encontrada no site oficial da API, me deixou bastante curioso. Veja com seus próprios olhos:
“Nearby uses a combination of Bluetooth, Bluetooth Low Energy, Wi-Fi and near-ultrasonic audio to communicate a unique-in-time pairing code between devices. The server facilitates message exchange between devices that detect the same pairing code. When a device detects a pairing code from a nearby device, it sends the pairing code to the Nearby Messages server for validation, and to check whether there are any messages to deliver for the application’s current set of subscriptions.” Fiquei principalmente interessado na parte que refere-se a “near-ultrasonic audio”.
Sobre o funcionamento desta API para pôr em prática o PubSub, ele funciona da seguinte maneira: o canal é criado a cada nova mensagem que um publicador deseja compartilhar. Para fornecer acesso a este canal, o publicador gera um pequeno token e troca o mesmo com outro dispositivo, pelos meios listados no parágrafo acima. Quando este dispositivo detecta o token, se comunica com o Nearby Messages Server para validar e checar se existe alguma mensagem ligada ao token em questão.
Depois de conhecer a API e ler sobre seu funcionamento, a necessidade de testar a API e criar algum aplicativo de exemplo estava explodindo. O resultado disso o leitor pode conferir na íntegra no meu GitHub:
O aplicativo construído tem o intuito de ser um compartilhador de um simples cartão virtual, com dados das principais redes sociais (Facebook, Twitter e Linkedin), além de uma foto.
Bem, agora vamos estudar alguns trechos de código que focam exclusivamente na Nearby Message API.
1) Inicialmente o leitor deverá criar um projeto no Google Console API, além de configurar as credenciais para a API que estamos estudando. Este passo é detalhado e pode ser seguido passo a passo neste link. Aqui o que nos interessa mais é o código.
2) No projeto criado no Android Studio é necessário indicar a Nearby no Gradle Script. No build.gradle do módulo, no objeto de dependencies, a seguinte linha deve ser adicionada:
compile 'com.google.android.gms:play-services-nearby:11.6.0'
3) Os layouts estão disponíveis no GitHub, no link referido anteriormente. Como nosso foco aqui é a API, não vamos detalhá-los. Porém, segue as duas imagens que mostram as duas únicas interfaces do projeto. A primeira contém entradas de texto onde o usuário define suas redes sociais e uma foto. No xml que o leitor vai encontrar no GitHub, perceberá que já estão preenchidos com minhas redes sociais. Fiz isso para facilitar meus testes, somente por isso.
A segunda interface é exibida quando o usuário recebe um “cartão” virtual, com dados de rede social e uma foto.
4) As duas interfaces possíveis da aplicação estão na mesma activity. Somente são mostradas ou escondidas de acordo com o contexto. No método onCreate da única Activity que temos no projeto, cria-se uma instância da classe abstrata MessageListener. Este ouvidor receberá as mensagens do Nearby Messages Server em resposta a um token compartilhado.
O trecho de código no MainActivityK está aqui:
E o exemplo no MainActivity está aqui:
No momento que uma mensagem é recebida, o método onFound é invocado. Na lógica da nossa aplicação, apenas configuramos os valores nos campos TextView das redes sociais e trocamos a visibilidade dos dois containers.
5) Segundo o conceito do Publisher-Subscriber, o assinante (Sub) deve assinar um canal, um broker, ou como queira chamar. O importante é que o gerador de mensagem deve ser assinado pelos seus interessados. Isso foi feito no nosso código na sobrescrita dos métodos onStart e onStop, que fazem parte do ciclo de vida de uma Activity.
O trecho de código no Kotlin está aqui:
E o trecho de código no Java está aqui:
Perceba que a lógica é bem simples. Uma instância de MessagesClient é recuperada chamando o método estático getMessagesClient. Depois os métodos subscribe e unsbscribe são usados para assinar ou remover a assinatura no Nearby Message Server.
No onStop o leitor deve ter percebido que um teste lógico é feito para saber se uma mensagem já foi publicada no momento que o aplicativo está entrando no estado stopped. Neste caso, cancelamos a publicação da mesma.
6) O papel do assinante no padrão Publisher-Subscriber já está claro e já foi codificado. E o publisher? ¿Donde estás? No código da nossa Activity temos um método share, que será acionado como resposta ao evento de clique no botão da interface.
O método recupera uma instância de MessagesClient e usa o método estático publish, passando um primeiro parâmetro, que é uma instância de Message e, um segundo parâmetro, que é uma instância de PublishOptions. Esta classe de opções, por sua vez, está configurando um PublishCallback, para saber se o envio de uma mensagem expirou e, configura a estratégia de envio, que, por sua vez, é uma instância de Strategy.
Neste Strategy estamos apenas configurando o ttl seconds, que é time-to-live da mensagem em segundos. A API oferece três constantes para isso: TTL_SECOND_MAX, TTL, SECOND_DEFAULT e TTL_SECOND_INFINITE. Este último ainda não permite seu uso, embora exista na API. O second max tem um valor de 86400, que é a quantidade de segundos de um dia exato. O default tem 300 segundos, ou seja, 5 minutos.
O código que discutimos neste último item, em Java, está disponível aqui:
E em Kotlin, aqui:
Espero que este simples exemplo tenha mostrado a simplicidade e o poder desta API. O protocolo Publisher-Subcriber tem seu imenso valor no desenvolvimento mobile, e a Nearby Message comprova isso.