Transcript
Page 1: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Encontros Comunitários GU

Mobile-RS Websockets e Android

Apoio:

Page 2: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

jacksonfdam

http://about.me/jacksonfdamhttps://bitbucket.org/jacksonfdamhttps://github.com/jacksonfdamhttp://linkedin.com/in/jacksonfdam@jacksonfdam

Page 3: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

GU Mobile RS

Somos um grupo destinado a compartilhar e promover encontros de desenvolvedores mobile no Rio Grande do Sul.

EventosColaboramos para eventos de desenvolvimento.

OficínasRealizamos encontros para por em prática o desenvolvimento de aplicativos móveis em diversas plataformas.

Page 4: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Aplicações real-time

Quando se fala de aplicações real-time, estamos técnicamente falando de conexões bi-direcionais, que na prática, é uma conexão que se mantem aberta (keep-alive) para que os clientes interajam com o servidor em uma única conexão aberta. A grande vantagem disso é de não precisar mais das requisições assíncronas (AJAX) para simular uma “ação quase real-time”, digo quase pois AJAX não é uma conexão bi-direcional capaz de se manter aberta até o término de seu processamento.

Page 5: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Realtime App

• Chat• Stream de atividades• Notificações• Colaboração• Jogos multiplayer• Dados em tempo real• Dashboards• Experiências 2 telas

Page 6: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

CometComet é um modelo de aplicação web que tem como principal característica a utilização de uma ligação persistente HTTP que permite ao servidor transmitir dados para o cliente sem que exista um pedido explícito.

Esta técnica é chamada de Tecnologia Push.

O termo Comet representa um grupo de recursos e técnicas utilizados para a interação bilateral.

Fonte:http://en.wikipedia.org/wiki/Comet_%28programming%29

Page 7: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Websockets

É uma tecnologia que permite a comunicação bidirecional por canais full-duplex sobre um único soquete (TCP).

SuporteTodos os browsers mais atuais com exceção do browser Android suportam a ultima especificação do protocolo.• Internet Explorer

10+• Mozilla Firefox 4+• Safari 5+• Google Chrome 4+• Opera 11+

Page 8: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Protocol Handshake

Enquanto o protocolo WebSocket em si é desconhecido dos servidores proxy e firewalls, ele possui um handshake HTTP compatível para que os servidores HTTP possam compartilhar seu padrão HTTP e HTTPS portas (80 e 443) com um gateway ou servidor WebSocket.

O protocolo WebSocket define um ws:// e wss:// prefixo para indicar um WebSocket e uma conexão segura WebSocket, respectivamente.

Page 9: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Protocol Handshake

Client request

GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chat, superchatSec-WebSocket-Version: 13Origin: http://example.com

Server response

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat

Page 10: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Protocol Handshake

Uma vez que a conexão é estabelecida entre o cliente e o servidor, podemos enviar dados ou estruturas de texto em ambas as direções no modo full-duplex.

Page 11: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Example

var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");

Sintaxe Javascript

Page 12: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Example

exampleSocket.onopen = function (event) { exampleSocket.send("Here's some text that the server is urgently awaiting!"); };

Sintaxe Javascript

Page 13: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

WebSocket Example

exampleSocket.onmessage = function (event) { console.log(event.data);}

Sintaxe Javascript

Page 14: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

E agora?

Page 15: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

NODE.JSWTF? Conhecendo a tecnologia

Page 16: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Node.js se tornou popular devido a sua facilidade em trabalhar com real-time, simplesmente por que o protocolo WebSockets (Protocolo do HTML5 para conexões bi-direcionais) utiliza-se Javascript também.

• Orientado a eventos• Lado do servidor • JS não bloqueante

Mais em: http://udgwebdev.com/nodejs-para-leigos-introducao/

Page 17: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Google V8 Motor• Engine JS Open source do Google (usado no

Google Chrome)• Sem JIT (Just-In-Time), todos JS compilado para

assembler• Otimizações como inlining, elisão de propriedades

em tempo de execução ... • Garbage Collector implementado / melhorado

http://en.wikipedia.org/wiki/Inlininghttp://en.wikipedia.org/wiki/V8_(JavaScript_engine)http://en.wikipedia.org/wiki/Copy_elision

Page 18: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

CommonJS • Conjunto de especificações para JS fora do

navegador • Node.js implementa algumas especificações

– ex. módulos • Deve haver uma função chamada require• Deve haver uma var chamada exports

Page 19: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Módulos • O Node.js fornece alguns módulos principais como

o http, tcp, fs, sys... – procurará o módulo na pasta node_modules

hierarquicamente– se não for encontrado, vai olhar nos caminhos descritos

no NODE_PATH

var http = require ('http');

Page 20: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Exemplo de Módulo

var PI = Math.PI; exports.area = function (r) {

return PI * r * r; }; exports.circumference = function (r) { return 2 * PI * r; };

Exemplo de definição em meuModulo.js

var meuModulo = require(‘./meuModulo .js’);

Include do meuModulo.js em outro arquivo

Page 21: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Gerenciamento de Dependências

• Node packet manager (npm) • express (rotas)• socket.io (websockets)• ..

Page 22: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Package.json

{ "name": ”Fisl 15 Chat", "version": "1.0.0", "description": "Real time chat com Android", "author": ”Jackson F. de A. Mafra", "scripts": { "start": "node app.js" }, "dependencies": { "socket.io": "latest", "express": "latest", "jade": "latest" } }

npm install

Page 23: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Webserver em Node.JS

var http = require('http'); http.createServer(function (req, res) {

res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World, Wellcome to FISL15\n'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');

node app.js Server running at http://127.0.0.1:1337/

Page 24: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Express.js

Uma web framework para node.js inspirada em sinatra

var express = require('express'); var app = express(); app.get('/', function(req, res){

res.send('Hello World'); }); app.listen(3000);

Page 25: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Socket.io

É uma camada de abstração para WebSockets com fallback para : • Flash socket• AJAX Long-polling• AJAX multi-part streaming• JSONP polling• iFrame

Page 26: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Manipulação Eventos

io.sockets.on('connection', function(socket) {}); //initial connection from client

socket.on('message', function(message) {}) //message handler triggered when message is received

socket.on('disconnect', function() {}) //triggered when socket disconnects

socket.on('custom_event', function(data) {}) //event handler for custom event

Page 27: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Enviando Mensagens

messages socket.send(JSON.stringify({user:’jackson', message: 'Welcome to Fisl15'}) ); //sends a message to the connected client

socket.broadcast.send(JSON.stringify({user:’jackson', message: 'Welcome to Fisl15'}) ); //sends a message to all clients except the owner of the socket

Page 28: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Emitindo Eventos

socket.emit('user:join', {name: ’jackson'}); //triggers a custom event

socket.broadcast.emit('user:joined', data); //sends a message to all clients except the owner of the socket

Page 29: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Node.js

Anexar informações ao socket

socket.set('nickname', data.name, <optional_callback>);

Page 30: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

ANDROIDPreparando o aplicativo cliente

Page 31: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Injeção de Dependência

Injeção de dependência é um padrão de projeto de software que permite a remoção de dependências hard-coded e torna possível para mudá-los, seja em tempo de execução ou em tempo de compilação. [Fonte: Wikipedia]

http://en.wikipedia.org/wiki/Dependency_injection

Page 32: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Injeção de Dependência

A Injeção de Dependências (também conhecida como Inversão de Controle) está presente em diversos frameworks populares como Spring ou Google Guice. Porém, estes últimos foram desenvolvidos pensando na JVM e não em ambientes móveis como o Android. Enquanto o RoboGuice procura melhorar a usabilidade do Guice no Android, o Dagger segue uma abordagem diferente, concentrando-se em funcionalidades simplificadas e melhor desempenho.

http://www.infoq.com/br/news/2012/10/dagger-injecao-android

Page 33: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Injeção de dependência

Injeção de Classes

Dagger

Injeção de views

Butter Knife

Universal

RoboGuiceAndroid Annotations (AA)

Mais em: http://java.dzone.com/articles/how-become-lazy-productive

Page 34: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o projeto

O cliente de chat Android deve ser capaz de enviar e receber mensagens a partir de uma sala de bate-papo.

Inicie o Android Studio e crie um novo projeto chamado FislChat com o package io.github.gumobilers.fislchatCriar uma atividade em branco chamado ChatActivity

Page 35: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Definindo o layout

O fragmento irá conter o layout da nossa aplicação de chat. Abra o fragment_chat.xml (ou o nome que você deu para o layout) e defina:

• Uma ListView que conterá as mensagens de bate-papo (dica: android: stackFromBottom = "true" android: transcriptMode = "alwaysScroll" pode ajudá-lo)

• Um EditText para escrever a mensagem que deseja enviar para a sala de bate-papo

• Um botão para enviar a mensagem• Execute o aplicativo e ver que você começa o layout

desejado

Page 36: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando o RoboGuice

A instalação do RoboGuice requer que você baixe os seguintes arquivos JAR e adicioná-los ao seu classpath.

http://repo1.maven.org/maven2/org/roboguice/roboguice/2.0/roboguice-2.0.jarhttp://repo1.maven.org/maven2/com/google/inject/guice/3.0/guice-3.0-no_aop.jarhttp://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar

Page 37: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

RoboGuice: Dependency Injection for Android - Michael Burtonhttps://www.youtube.com/watch?v=6wU2vwwiwPE

Page 38: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando o RoboGuice

Para utilizar RoboGuice para a injeção de dependência, é preciso adicioná-lo como uma dependência do projeto. • Abra o arquivo gradle.build e adicionar a dependência RoboGuice

sob o elemento dependências .• compile 'org.roboguice: roboguice: 3.0b-experimental’ • Certifique-se de que RoboGuice aparece em suas bibliotecas

externas • Nossos componentes Android precisará estender classes específicas

RoboGuice ter DI no lugar. • Edite seu fragmento e estendem-se desde RoboFragment • Edite você Atividade e estendem-se desde RoboFragmentActivity

Page 39: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Huston we have a problem!

Em caso de problemas:No Android Studio clique no botão Sync Project with Gradle File, deixe o AVD Manager fazer o trabalho. Sem restart, sem ./gradlew clean ou ./gradlew build.

Tambem pode ir em Tools-->Android-->Sync Project with Gradle File.

Page 40: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Injetando dependências

Para interagir com os componentes de layout, vamos usar a injeção dependência RoboGuice

• Adicionar um campo privado do tipo ListView e anotá-lo com @InjectView para obter uma referência da lista declarados (ex: @InjectView (R.id.messageList) private mMessageList ListView;)

• Adicionar um campo privado do tipo EditText e anotá-lo com @InjectView para obter a referência da entrada de texto declarado.

• Adicionar um campo privado do tipo Button e anotá-lo com @InjectView para obter a referência do botão declarado.

Page 41: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando a lógica

A injeção acontece durante o método onViewCreated em seu fragmento, de forma a garantir que as dependências já foram injetadas estaremos interagindo com eles no mesmo ponto.

1. Sobrescrever o método onViewCreated:

@Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); }

1. De forma a interagir com o elemento da lista, é preciso fornecer um adaptador. 2. Vamos adicionar um simples ArrayAdapter de String para agora:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1);mMessageList.setAdapter(adapter);

Page 42: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Injetando um serviço de sistema

Vamos agora fazer o nosso telefone vibrar quando enviar uma mensagem.

Adicionar a permissão Vibrar em seu AndroidManifest.xml

<uses-permission android:name="android.permission.VIBRATE" />

Adicionar um campo particular do tipo Vibrator em seu fragmento e anotá-lo com a JSR-330 anotação @Inject.

Adicionar a lógica para vibrar 1000 milissegundos quando o envio da mensagem

Page 43: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

NODE.JSConstruindo o servidor com Node.js e Socket.io

Page 44: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o projeto Node.js

Para ter a estrutura do projeto, vamos contar com o express.js (semelhante ao sinatra). Instale expressar globalmente com o seguinte comando:

npm install –g express

Agora vamos criar um aplicativo baseado expressa chamado fislchat

express fislchat

Page 45: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o projeto Node.js

A seguinte estrutura será criada

create : fislchat create : fislchat/package.json create : fislchat/app.js create : fislchat/public create : fislchat/views create : fislchat/views/layout.jade create : fislchat/views/index.jade create : fislchat/public/images create : fislchat/routes create : fislchat/routes/index.js create : fislchat/routes/user.js create : fislchat/public/stylesheets create : fislchat/public/stylesheets/style.css create : fislchat/public/javascripts

Page 46: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o projeto Node.js

Observe que um arquivo chamado package.json contendo as dependências foi criado. Execute npm install para adicioná-las ao projeto (verifique que a pasta node_modules é criada e contém as dependências).

O app.js é o ponto de entrada para o nosso aplicativo, ele importa os módulos necessários, define algumas rotas e cria o servidor http. Abra e dê uma olhada nisso. Isso deve ser o suficiente para começar a nossa aplicação.

Executar node app ou npm start para iniciar o aplicativo. Verifique se digitando 'http://localhost:3000/' no seu navegador lhe dá a página de boas-vindas.

Page 47: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando o Socket.io

Até agora, você deve estar familiarizado com packages.json. De forma que para adicionar o suporte ao Socket.io precisamos defini-lo como uma dependência de tal arquivo, abra-o e adicione: "socket.io": "~ 0.9.16".

Execute npm install novamente para buscar a dependência.

Vamos agora criar um módulo que irá encapsular a lógica do socket.io. Crie um arquivo chamado socket.js dentro da pasta rotas.

Este módulo irá usar a dependência socket.io já definida. Importe no módulo :

var socketio = require ('socket.io');

Page 48: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando o Socket.io

Os módulos contêm lógica privada para a próprio módulo, que encapsulam a lógica, mas lembre-se que eles também podem expô-la usando a convenção CommonJS (com exportações das variáveis). Vamos expor uma função chamada initialize então podemos inicializá-la a partir de outro módulo:

exports.initialize = function(server) { io = socketio.listen(server);}

Nós adicionamos um parâmetro de servidor (este será o servidor http já criado no arquivo app.js) e nós inicializamos socketio, a fim de começar a aceitar conexões. Agora é hora de usar o nosso módulo.

Page 49: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Usando nosso módulo Socket.io

var server = http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port'));});

Abra a app.js e adicione o módulo que acabamos de criar

var io = require (’./routes /socket.js.').

Lembre-se que nós expomos a função initialize esperando um servidor http como parâmetro. Se você rolar no final do arquivo, você vai ver como o servidor http é criado (por padrão escutar no porto 3000).

Permite obter uma referência nesse servidor para que possamos passá-lo para o módulo

Page 50: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Usando nosso módulo Socket.io Agora você pode chamar a função initialize, passando o parâmetro do servidor:

io.initialize (server);

Inicie o aplicativo novamente (app nó) e verificar se você ver algo como

info - socket.io

iniciada no console.

Page 51: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Manipulação de eventos

Agora temos o app já ouvindo as conexões WebSocket , mas precisamos lidar com os eventos ( nova conexão, desconexão , mensagens ...) . Vamos adicionar um listener de conexão dentro do método initialize :io.sockets.on('connection', function(socket) { // All your handlers here, socket will be the connected client});

Page 52: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Manipulação de eventos

Fornecer um handler para o evento 'user : setname ‘.

Este será acionado pelo cliente logo após a conectar. ( Dica : . Lembre socket.on ( 'event' , function ( data) { })

A mensagem recebida será algo semelhante a { ' nickname': ' jackson'} .

Defina o valor para a sessão de socket para que possamos lembrar o nome do usuário e não forçá-lo a ser enviar toda vez ( dica: use socket.set ) .

Transmita uma mensagem como { ‘mensagem: ' jackson entrou !’ } para todos os usuários conectados .

Page 53: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Manipulação de eventos

Forneça um handler para o evento 'user : mensagem’.

Este evento será acionado quando um usuário envia uma mensagem para o chat.

Os dados será um JSON semelhante a este: {' mensagem ': ' Olá '} .

Transmita a mensagem para todos os outros clientes que adicionaram o apelido para ele ( dica: use socket.get(var, function (err, nickname) {}) )

para obter o apelido previamente armazenado ) .

A mensagem resultante deve ser como :{' mensagem ': ' Olá ', ' apelido ': ' jackson'}

Page 54: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Manipulação de eventos

BÔNUS:

Guarde os nomes de usuário em um array var users = []; , armazenar o nome quando se conectar e remova-o quando ele se desconectar.

Page 55: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

ANDROIDComunicando o cliente com o socket.io

Page 56: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Incluindo Dependências

Não há nenhum suporte para Socket.io no Android , mas vamos adicionar uma biblioteca a partir de um repositório Maven. Abra o arquivo build.gradle e adicione o seguinte repositório sob o elemento repositórios:

repositories { mavenCentral() maven { url "http://audiobox.keytwo.net" }}

Vamos adicionar agora as duas dependências que requerem

compile 'io.socket:socket.io-client:0.2.1'compile 'com.squareup:otto:1.3.4'

Socket-io: https://github.com/fatshotty/socket.io-java-clientOtto: https://github.com/square/otto

Page 57: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o serviço

De forma a manter a conexão em segundo plano, vamos criar um serviço que irá gerenciar nossos WebSockets. Crie uma classe chamada ChatService que estenda RoboService.

Adicione a definição de serviço no arquivo AndroidManifest.xml, para conhecimento da aplicação: <service android:name=".ChatService" />

Agora que temos o serviço, nós vamos ter que iniciá-lo. Um bom lugar para iniciá-lo, seria de uma classe de aplicação(Application).

Criar e uma classe chamada ChatApplication e inicie o serviço no método onCreate. Você deve ter algo semelhante a isto:

Page 58: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Criando o serviço

public class ChatApplication extends Application {

@Override public void onCreate() { super.onCreate();

// Start the service here } }

Volte para o arquivo AndroidManifest.xml e adicione o nome do aplicativo que você acabou de criar:

<application android:name=".ChatApplication"

Page 59: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicionando o evento de

barramentoOtto é um barramento de evento destinado a separar diferentes partes do seu aplicativo enquanto ainda permite que elas se comuniquem de forma eficiente.

http://square.github.io/otto/

Page 60: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Bus bus = new Bus(); //creates the bus (better use dependency injection)

bus.post(new ServerMessage("This is awesome")); //publish the message //synchronous delivery

Publicando

Adicionando o evento de

barramento

Page 61: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

@Subscribe public void receiveMessage(ServerMessage serverMessage) {

// TODO: React to the event somehow!

}

Assinando

Adicionando o evento de

barramento

Page 62: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

• register(), unregister(), post() • @Subscribe, @Produce• Thread confinement • Testes simples

Otto API

Adicionando o evento de

barramento

Page 63: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Vamos criar um módulo RoboGuice para tornar o singleton Bus e reutilizá-lo em todo o aplicativo. Criar uma classe interna no ChatApplication:

Otto API

Adicionando o evento de

barramento

class ChatModule implements Module { @Override public void configure(Binder binder) { // Figure out how to declare a singleton Bus } }

Page 64: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Agora adicione essa linha logo antes de iniciar o serviço, para que o RoboGuice saiba sobre o nosso módulo:

Otto API

Adicionando o evento de

barramento

RoboGuice.setBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE, RoboGuice.newDefaultRoboModule(this), new ChatModule());

Page 65: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Agora você está pronto para injetar o Bus tanto no ChatService e ao ChatFragment. Crie um campo privado do tipo Bus e usar a anotação @Inject.

Otto API

Adicionando o evento de

barramento

Page 66: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Uma última coisa, a fim de receber eventos (também se aplica aos produtores), uma instância de classe precisa se registrar com o barramento. Adicione o seguinte código para o ChatFragment

Otto API

Adicionando o evento de

barramento

@Override public void onResume() { super.onResume(); mBus.register(this); }

@Override public void onPause() { super.onPause();

// Always unregister when an object no longer should be on the bus. mBus.unregister(this); }

Page 67: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicione o seguinte código para o ChatService

Otto API

Adicionando o evento de

barramento

@Override public void onCreate() { super.onCreate(); mBus.register(this); }

@Override public void onDestroy() { super.onDestroy(); mBus.unregister(this); }

Page 68: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicione a permissão INTERNET para o seu AndroidManifest.xml para que possa se conectar ao servidor.

Interagindo com o Servidor com o

Socket.io

<uses-permission android:name="android.permission.INTERNET"/>

Vamos agora abrir um WebSocket com o servidor no ChatService. Crie um campo privado do tipo SocketIO e um método de inicialização (initialize) para inicializar Socket.io:

Page 69: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

socket = new SocketIO("http://127.0.0.1:3000/");

socket.connect(new IOCallback() { @Override public void onMessage(JsonElement json, IOAcknowledge ack) { System.out.println("Server said:" + json.toString()); }

@Override public void onMessage(String data, IOAcknowledge ack) { System.out.println("Server said string: " + data); }

@Override public void onError(SocketIOException socketIOException) { System.out.println("an Error occured"); socketIOException.printStackTrace(); }...

Interagindo com o Servidor com o

Socket.io

Page 70: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

@Override public void onDisconnect() { System.out.println("Connection terminated."); }

@Override public void onConnect() { System.out.println("Connection established"); }

@Override public void on(String event, IOAcknowledge ack, JsonElement... args) { System.out.println("Server triggered event '" + event + "'"); } });

Interagindo com o Servidor com o

Socket.io

Page 71: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Logo após ter uma conexão bem-sucedida, emite evento de user: setname e enviar uma mensagem como {'apelido': ’jackson'} (você pode codificar o nome de usuário até agora)

Definindo o apelido

Page 72: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

• servidor irá enviar mensagens JSON no seguinte formato {’message': ’Ola', 'Apelido': ’jackson'}.

Crie uma classe chamada ServerMessage que representa esse esquema e sobreescreve o método toString (vamos usá-lo para exibir as mensagens na interface do usuário).

Vamos interpretar mensagens sem apelido para ser mensagens do sistema, então isso vai como vamos mostrar mensagens:

As mensagens do sistema -> / / mensagem (ex:, / / jackson entrou na sala) Mensagens do usuário -> apelido: mensagem (ex:, jackson: Chatiado!)

Recebendo mensagens

Page 73: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

public String toString() { return nickname != null ? nickname + ": " + message : "//" + message; }

Agora você pode implementar o método onMessage (a versão String), convertendo a mensagem recebida para um ServerMessage com Gson (você tem já como uma dependência, dica: use o método fromJson).

Esta mensagem precisa ser exibida na interface do usuário, mas como queremos ter tudo dissociado, vamos enviá-la para o barramento de evento, para um assinante pode processá-lo. AVISO: Por padrão, toda a interação com uma instância Bus é confinada na Main Thread, mas o serviço está sendo executado em uma Thread diferente. A fim de ser capaz de postar o evento para a Main Thread apartir do ChatService, estaremos usando uma solução de meio hacky.

Recebendo mensagens

Page 74: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

private final Handler mHandler = new Handler(Looper.getMainLooper());

public void post(final Object event) { if (Looper.myLooper() == Looper.getMainLooper()) { mBus.post(event); } else { mHandler.post(new Runnable() { @Override public void run() { mBus.post(event); } }); } }

Copie e cole o seguinte método no ChatService e postar a mensagem de usá-lo:

Recebendo mensagens

Page 75: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Temos agora a mensagem publicada para a o barramento, vamos adicionar um assinante para o evento.

O assinante deve ser definido no ChatFragment para que possamos atualizar o adaptador base no evento.

Altere a definição do adaptador de ArrayAdapter <String> para ArrayAdapter <ServerMessage> e atualizá-lo a partir do método de assinantes.

Execute o aplicativo e verificar que as mensagens são recebidas e adicionado à lista.

Recebendo mensagens

Page 76: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Quando pressionar o botão Enviar queremos que as mensagens sejam enviadas para o WebSocket.

Para isso, vamos criar uma classe chamada ClientMessage que representa o esquema a ser enviado ({'mensagem': 'Olá'}).

Usando a instancia de barramento que injetamos, postamos a mensagem e definimos um assinante no ChatService , responsável por enviá-lo para a WS (dica: use Gson novamente para converter de Object para String, toJson)

Enviando mensagens

Page 77: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

BROWSERCriando um cliente HTML

Page 78: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Crie um arquivo em seu diretório público chamado chat.html (O Node.js irá servi-la como um recurso estático) e adicione o seguinte esqueleto HTML5:

Construindo o cliente do navegador

<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Mobos Chat</title> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--></head><body></body><script src="/socket.io/socket.io.js" ></script><script src="http://code.jquery.com/jquery-1.10.1.min.js"></script></html>

Page 79: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Adicione um input para escrever a mensagem, um botão e um div para exibir as mensagens de bate-papo.Crie um arquivo chamado chat.js dentro da pasta javascript para encapsular a lógica do socket.io

Construindo o cliente do navegador

var socket = io.connect('http://localhost'); socket.on('yourevent', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); });

var socket = io.connect('http://localhost'); socket.on('yourevent', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); });

Page 80: Aplicações Realtime em Android | Fisl 15 | GuMobileRS

Obrigado!@jacksonfdam