Usando Redis no Azure com Xamarin.Android

O Redis é um projeto open source (sob a licença BSD), com uma estrutura de dados em memória, podendo ser usado com uma base de dados, cache e message broker. Ele suporta estruturas de dados tal como strings, hashes, listas, conjuntos, conjuntos classificados com consultas de dados, imagens, hyperloglogs e indices geo-espaciais com consultas de raio. O Redis tem uma replicação embutida, aceita scritps feitos em LUA, despejo em LRU, transações em níveis diferentes de persistencia em disco, e oferece alta disponibilidade via o Redis Sentinel e particionamento automático com o Redis Cluster.

No Azure, as instâncias do Redis são divididas em:

Basic (C0): Ideal para testes e desenvolvimento
Standard (C1): Cache em produção com replicação master/slave
Premium (P1): Persistencia de dados e desenhado para o máximo de escalabilidade e integração.

Clique aqui para ver os preços diretamente no site do Azure.

Dica!: Somente é possivel alterar as instancias para cima, isto é, de Basic para Standard. Então cuidado, se for fazer um teste na Premium e quiser voltar para Basic, não será possível, somente removendo e criando novamente.

Vamos começar "instalando" uma instância do Redis no Azure. Entre no portal e procure por Cache Redis > Adicionar > Escolha um nome e tipo de assinatura > Grupo de Recursos > Localização > Criar

Dica!: O Redis vem configurado padrão com uma conta C1 e para alterar é necessário clicar no Tipo de Preço e alterar para C0.

Dica2!: Geralmente os preços no Oeste dos EUA 2 são mais baratos.

Dica3!: No grupo de recursos, gosto de chamar o grupo pelo "produto" e pelo localidação. Exemplo: Default-Redis-EastUS2

Pronto! Enquanto o Azure faz o deploy vamos criar um projeto Xamarin.Android novo. No projeto de um duplo click em Proprierties (Propriedades) e vá em Android Manifest. Selecione as opções INTERNET, ACCESS COARSE LOCATION e ACCESS FINE LOCATION.

Vamos precisar dos últimos dois apenas para pegar os dados do GPS.

Bora fazer código!

[Activity(Label = "XamarinWithRedis", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity  
{
     protected override void OnCreate(Bundle bundle)
     {
         base.OnCreate(bundle);
         // Set our view from the "main" layout resource
         SetContentView(Resource.Layout.Main);
         // Get our button from the layout resource,
         // and attach an event to it
         Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += (sender, e) => {  
         LocationManager locationManager = (LocationManager)GetSystemService(LocationService);
         var locationListener = new MyLocationListner();
         locationManager.RequestLocationUpdates(LocationManager.GpsProvider, 5000, 10, locationListener);
}
     }
}

public class MyLocationListner : ILocationListener  
{
    public IntPtr Handle
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public void Dispose()
    {
        throw new NotImplementedException();
    }
    public void OnLocationChanged(Location location)
    {
        Log.Debug("TAGGPS", "Location changed: Lat: " + location.Latitude.ToString() + " Lng: " + location.Longitude.ToString());
    }
    public void OnProviderDisabled(string provider)
    {
        throw new NotImplementedException();
    }
    public void OnProviderEnabled(string provider)
    {
        throw new NotImplementedException();
    }
    public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
    {
        throw new NotImplementedException();
    }
}

Com sorte isso vai compilar e vai comecar a mostrar no Output a localização GPS.

Nuget

A implementação que vou usar é a do StackExchange.Redis.
StackExchange.Redis

using StackExchange.Redis;  
using Newtonsoft.Json;

public class MainActivity : Activity  
{
private const string RedisConn = "redisdotnetfloripa.redis.cache.windows.net:6380,password=COLOQUE_AQUI_O_PASSWORD_GERADO,ssl=True,abortConnect=False";

public ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(RedisConn);

public IDatabase cache;

     protected override void OnCreate(Bundle bundle)
     {
         base.OnCreate(bundle);
         // Set our view from the "main" layout resource
         SetContentView(Resource.Layout.Main);
         // Get our button from the layout resource,
         // and attach an event to it
         Button button = FindViewById<Button>(Resource.Id.MyButton);
         button.Click += (sender, e) => {
LocationManager locationManager = (LocationManager)GetSystemService(LocationService);  
         var locationListener = new MyLocationListner();
         locationManager.RequestLocationUpdates(LocationManager.GpsProvider, 5000, 10, locationListener);
         // Dentro do cache é possivel tem N databases
         // Por exemplo: Database(0) é o movimento GPS, já o Database(1) são os dados dos veículos cadastrados.
         cache = connection.GetDatabase(0);
         }
     }
}

Com isso, ao clicar no botão, estamos iniciando o cache para receber os dados do GPS na função que vamos criar abaixo.

[Serializable]
public class GpsViewModel  
{
public string Chave {get;set;}  
public string Lat {get;set;}  
public string Long {get;set;}  
}

public void SalvaGPS(GpsViewModel pGps)  
{
var redisKey = pGps.Chave; // este é o "indíce" do registro para consulta posterior  
var json = JsonConvert.SerializeObject(pGps); // o valor a ser salvo  
var ts = TimeSpan.FromDays(6); // tempo que a informação ficará retida dentro do Redis.  
var retorno = await cache.StringSet(redisKey, json, ts);  
}

Lembra deste trecho do código?

public void OnLocationChanged(Location location)  
    {
        Log.Debug("TAGGPS", "Location changed: Lat: " + location.Latitude.ToString() + " Lng: " + location.Longitude.ToString());
    }
Dentro dele vamos colocar a chamada do método de salvar a localização do aparelho.

public void OnLocationChanged(Location location)  
    {
        Log.Debug("TAGGPS", "Location changed: Lat: " + location.Latitude.ToString() + " Lng: " + location.Longitude.ToString());
        var gpsModel = new GpsViewModel { Chave = "Nexus6p", Lat = location.Latitude.ToString(), Long = location.Longitude.ToString() };
        var retorno = SalvaGps(gpsModel);
    }

E agora como que eu verifico os dados dentro do cache? Tenho que montar outra aplicação para isso? Pois é, infelizmente o Azure ainda não dispõe de uma ferramenta própria para visualização. Vamos usar o Redsmin que é gratuito para uma instância.

Após criar a sua conta e logar, vá em "Select a server > Add a redis instance"
Criando uma instância Redis

E lá você vai encontrar a opção "How to connect Azure Redis Cache" que mostra passo a passo como efetuar a conexão.

Depois no menu, é selecionar Connect ao lado da instância cadastrada e ver os dados sendo salvos. :)

Dúvidas? Sugestões?

Marco A. Ghostman

Empreendedor desde os 18 anos, sócio da MASS Labs, empresa de tecnologia, hoje, voltada para o mercado de mobilidade urbana. Desenvolvedor .NET com expertise em aplicações móveis.

Florianópolis/SC