Desenvolvendo aplicações peer-to

Transcrição

Desenvolvendo aplicações peer-to
Antonio Augusto Mariano da Silva
Ricardo Augusto Miguel
Ricardo Ribeiro Tavares
Desenvolvendo aplicações
peer-to-peer em JAVA com
JXTA
São Paulo
2003
SUMÁRIO
1. INTRODUÇÃO .................................................................................................................... 6
2. CONCEITOS E ARQUITETURAS DE REDES P2P.....................................................11
2.1 CARACTERÍSTICAS DAS REDES P2P...................................................................... 11
2.2 PROCESSAMENTO DISTRIBUÍDO: SETI@HOME .................................................12
2.3 REDES P2P COM INDEXAÇÃO CENTRALIZADA: O NAPSTER .........................13
2.4 A REDE DESCENTRALIZADA: PROJETO GNUTELLA.........................................14
3. INTRODUÇÃO AO JXTA ................................................................................................ 20
3.1 PRINCIPAIS CONCEITOS DA TECNOLOGIA .........................................................23
3.1.1 JXTA ID ................................................................................................................... 23
3.1.2 ADVERTISEMENTS................................................................................................ 24
3.1.3 PEERS ..................................................................................................................... 24
3.1.4 PEER GROUPS....................................................................................................... 25
3.1.5 PIPES....................................................................................................................... 25
3.1.6 ENDPOINTS............................................................................................................ 26
3.1.7 JXTA MESSAGES.................................................................................................... 26
3.1.8 RENDEZVOUS PEERS ........................................................................................... 27
3.1.9 RELAY PEERS......................................................................................................... 28
3.2 PROTOCOLOS JXTA ................................................................................................... 29
3.2.1 PEER DISCOVERY PROTOCOL (PDP) ................................................................ 30
3.2.2 PEER RESOLVER PROTOCOL (PRP) .................................................................. 31
3.2.3 PEER INFORMATION PROTOCOL (PIP) ............................................................ 33
3.2.5 PIPE BINDING PROTOCOL (PBP)....................................................................... 34
3.2.6 ENDPOINT ROUTING PROTOCOL (ERP)........................................................... 36
4. JXTA SHELL ..................................................................................................................... 39
4.1 CONFIGURAÇÃO INICIAL JXTA SHELL................................................................. 40
4.2 COMANDOS JXTA SHELL ......................................................................................... 43
4.2.1 MAN......................................................................................................................... 43
4.2.2 PEERCONFIG......................................................................................................... 44
4.2.3 RDVSTATUS............................................................................................................ 44
4.2.4 ENV.......................................................................................................................... 44
4.2.5 CAT.......................................................................................................................... 44
4.2.6 GREP ....................................................................................................................... 44
4.2.7 HISTORY ................................................................................................................. 45
4.2.8 VERSION ................................................................................................................. 45
4.2.9 EXIT......................................................................................................................... 45
4.2.10 GROUPS................................................................................................................ 45
4.2.11 PEERS ................................................................................................................... 46
4.2.12 WHOAMI ............................................................................................................... 47
4.3 CRIANDO UM GRUPO NA REDE JXTA ................................................................... 47
4.4 CONVERSANDO NA REDE JXTA ............................................................................. 50
4.5 CACHING DE ADVERTISEMENTS........................................................................... 52
4.6 A IMPORTÂNCIA DOS PIPES .................................................................................... 53
4
5. ESTUDO DE CASO: CHAT P2P DESCENTRALIZADO............................................ 56
5.1 CHAT CLIENTE/SERVIDOR X CHAT P2P ............................................................... 56
5.2 ARQUITETURA HÍBRIDA CLIENTE/SERVIDOR E P2P ........................................58
5.3 EXECUTANDO A APLICAÇÃO ................................................................................. 60
5.4 CONFIGURANDO O AMBIENTE JXTA.................................................................... 61
5.5 ANALISANDO O CÓDIGO FONTE............................................................................ 61
5.6 CLASSE CHAT.CHATAPP.JAVA ............................................................................... 62
6. CONCLUSÃO..................................................................................................................... 69
REFERÊNCIAS BIBLIOGRÁFICAS ................................................................................. 72
GLOSSÁRIO .......................................................................................................................... 77
APÊNDICE A – CÓDIGOS FONTE DA IMPLEMENTAÇÃO .......................................79
5
1. INTRODUÇÃO
No final da década de 60 a Internet foi concebida como um sistema originalmente
P2P, onde as máquinas participantes dessa rede trocavam informações com apenas alguns
servidores robustos. Com a popularização e o avanço dos navegadores, e o aumento da
capacidade de processamento dos servidores, a internet tornou-se uma rede de potentes
servidores entregando conteúdo para os clientes requisitantes.
Como proposta inicial da Internet haveria acesso irrestrito a todos os recursos da rede,
a qualquer momento, de qualquer lugar, com o uso de qualquer dispositivo. Apesar disso, a
Web, ainda hoje está sujeita a um modelo de rede capaz de inibir o acesso a recursos,
restringir a riqueza e a profundidade do conteúdo e até mesmo impedir o crescimento da
própria Web.
A Tecnologia P2P é um esforço concebido, com o objetivo de fornecer acesso total a
Web, acompanhando sua constante expansão e aprofundamento.
A popularidade de tecnologias de rede P2P aumentou dramaticamente nos últimos
anos. Esses serviços estão se proliferando cada vez mais, pela conveniência da comunicação
instantânea que proporcionam e pela redução constante dos limites de tráfego que permite a
distribuição de filmes, músicas e outros recursos com grande volume de dados.
As pessoas buscam, então, acesso a um conteúdo cada vez com maior qualidade.
6
A Web atual utiliza um modelo cliente-servidor no qual servidores centralizados
executam tarefas para clientes distribuídos. No modelo P2P, qualquer cliente autorizado pode
ter acesso a qualquer serviço na rede comunicando-se com o servidor em que o serviço está
residente.
Quanto à comunicação P2P, se necessitarmos de caminho inverso ou até mesmo para
uma máquina cliente conectar-se a um outro ponto remoto, diversos problemas e dificuldades
ainda são enfrentados, basta lembrar o funcionamento do popular software de mensagem
instantâneas ICQ. Utilizar o ICQ corretamente via um servidor proxy e principalmente através
de um firewall é uma tarefa que exige configurações especiais nesses servidores.
As maiorias das redes protegidas permitem apenas o tráfego de informações por
http/https, geralmente na porta 80/443. Para envio de mensagens assíncronas alguns softwares
usam técnicas como postagem de conteúdo xml e web-services para um servidor que conhece
ambos os nós, porém para a transferência de arquivos entre nós remotos isto é praticamente
impossível.
Outro exemplo clássico das dificuldades enfrentadas por aplicativos P2P como os
famosos compartilhadores de arquivos Kazaa e o antigo Napster, é a utilização adequada da
largura de banda. Precisamos considerar nestes aplicativos que a utilização de banda ocorre
principalmente na hora da transferência de arquivos entre as máquinas. Uma rede local
compartilhando 10 máquinas com uma banda de 256 k para download e 128 k para upload
(como atualmente ser fornecem os serviços de ADSL mais comuns no Brasil) é praticamente
sobrecarregada tanto agindo como cliente P2P ou como aplicação servidora de arquivos.
7
Porém uma das características de sucesso das redes P2P é que ela pode ser totalmente
descentralizada.
O maior problema enfrentado pelo Napster foi a questão jurídica da troca de arquivos
.mp3 entre os usuários. O que realmente o condenou ao “desaparecimento” foi o fato de ser
um aplicativo que utilizava metodologias de redes P2P híbridas. Sendo assim a lista de
arquivos .mp3 de seus usuários ficavam centralizadas em seu servidor, que “negociava”
depois a conexão dos pontos remotos. Com essa centralização tirá-lo do ar foi uma tarefa
relativamente simples para os advogados das grandes gravadoras. A solução do Napster
tecnicamente é uma solução bastante interessante, pois garantindo a centralização dos dados
diminui-se a redundância dos arquivos e ao mesmo tempo agiliza e facilita o processo de
pesquisa de arquivos, porém para um assunto tão polêmico como compartilhamento de mp3,
esta característica significou a morte desta rede.
Diante dessa questão da sobrevivência da rede independente de um servidor
centralizado, muitas técnicas surgiram e hoje são utilizados em aplicativos como o
compartilhador de arquivos e-donkey. A técnica é basicamente fazer com que cada cliente
“compartilhe” além dos arquivos também os nós de rede conhecidos e próximos. A grande
desvantagem é a forma como é realizada a pesquisa dos arquivos. Uma consulta simples pode
viajar por diversos nós até encontrar uma resposta, e mesmo você não tendo arquivo algum a
compartilhar seus recursos estarão sendo utilizado.
Como se tem visto nos últimos anos, os usuários da internet querem muito mais do que
receber conteúdo pela porta 80, e a explosão da utilização dos softwares descritos
anteriormente prova isso mesmo enfrentando os problemas mencionados acima.
8
Tentaremos resgatar neste estudo a real necessidade da cooperação entre os
computadores participantes da internet, utilizando assim uma estrutura de rede menos
centralizada e restrita. Apesar do assunto principal discutido aqui ser redes P2P não teremos
como fugir de conceitos computacionais tradicionais como criptografia, segurança, algoritmos
de compactação,redes tcp/ip entre outros, pois os mesmo sempre estarão sendo aplicados na
construção de aplicativos P2P.
Para o arquiteto de soluções P2P, muitos outros problemas acontecem, como por
exemplo a escolha adequada da tecnologia e plataforma a serem utilizadas.
Neste estudo estaremos mostrando a importância do framework JXTA para o
desenvolvimento de aplicações P2P em JAVA.
O objetivo principal de qualquer framework de desenvolvimento é aumentar a
produtividade e encapsular funcionalidades, permitindo ao desenvolvedor concentrar-se nas
características de sua aplicação, e não reescrevendo e testando funcionalidades que não dizem
respeito diretamente ao escopo inicial do seu projeto.
"O Projeto JXTA ampliará o acesso à Web e a profundidade do contúdo disponível",
Joy Bill (Sun Microsystems,Inc).
Através do JXTA a computação distribuída e as tecnologias não-hierárquicas entram
em ação.
9
Apesar de ser baseado na tecnologia P2P, o JXTA é muito mais do que uma proposta
P2P, pois oferece mecanismos para a criação e o fornecimento de uma categoria de serviços e
aplicativos inteiramente nova e para a ampliação dos serviços Web de locais fixos ou
centralizados para a borda da rede.
Considerando as dificuldades do tema abordado e para fixar e exemplificar os
conceitos aqui apresentados, estaremos desenvolvendo uma aplicação case onde os pontos
(Nós da rede) trocam mensagens de texto como em uma aplicação de chat tradicional.
Estaremos disponibilizando os códigos fonte para quem tiver interessado.
10
2. CONCEITOS E ARQUITETURAS DE REDES P2P
2.1 CARACTERÍSTICAS DAS REDES P2P
Nos últimos anos tivemos diversas aplicações P2P sendo usadas por milhões de
usuários. Para citar algumas das mais populares podemos lembrar do ICQ (I seek you) e do
Napster. Estas duas aplicações revolucionaram a utilização da internet e aproximaram cada
vez mais as pessoas conectadas através da internet.
Diversas funcionalidades podem ser fornecidas por dispositivos conectados em uma
rede P2P:
· Compartilhamento de arquivos e publicações.
· Armazenamento distribuído e compartilhamento de capacidade de armazenamento.
· Busca Semântica e distribuída entre os peers.
· Compartilhamento de capacidade de processamento e processamento distribuído
· Formação de grupos ou comunidades de peers.
· Colaboração de informações, trocas de mensagens instantâneas e comunicação entre
os peers.
Antes do surgimento das aplicações P2P, a utilização da internet por usuários comuns
consistia em uma rede praticamente cliente/servidor, com diversos clientes requisitando
conteúdo e serviços publicados por servidores com endereços fixos registrados no DNS
(Domain Name System) [TRUELOVE, K., 2001].
11
Com a inovação tecnológica e a popularização de diversos dispositivos com acesso a
Internet, como por exemplo, celulares de última geração e PDA’s (Personal Digital
Assistants), passamos a contar com uma rede mais transiente, na qual estes dispositivos
também são capazes de fornecer recursos, porém nem sempre estarão conectados ou
utilizando-os o mesmos endereços. O aumento da largura de banda, e a maior disponibilidade
de acesso fizeram com que os usuários sentissem a necessidade de uma rede mais
colaborativa, na qual a busca de conteúdo e serviços, além da interação com outros usuários,
deixa de ser privilégio de alguns servidores. Essas talvez tenham sido as motivações para o
constante crescimento das redes e aplicativos P2P [TRUELOVE, K., 2001]. Diversas
arquiteturas de aplicações tem sido utilizadas ao longo do tempo em aplicações P2P. A
seguir abordaremos o funcionamento básico de algumas aplicações importantes na evolução
de sistemas P2P.
2.2 PROCESSAMENTO DISTRIBUÍDO: SETI@HOME
O grande poder de processamento dos atuais computadores pessoais e a ociosidade da
maioria desses computadores, possibilitam o surgimento de aplicações com um
processamento realmente distribuído, espalhadas pela internet [SUN MICROSYSTEMS,
INC., 2001]. O projeto SETI@HOME (Search for Extraterrestrial Intelligence), com objetivo
de identificar vida inteligente fora do planeta terra, é um exemplo bem sucedido deste tipo de
aplicação. Ao instalar o screen-saver do projeto, estaremos contribuindo com parte dos
cálculos para análise de sinais de rádios, capturados diariamente por potentes telescópios.
Depois de realizada a análise dos dados obtidos quando o computador está ocioso, os
12
resultados são enviados para os servidores localizados na Califórnia, que mantém centralizado
todos resultados obtidos. Para realizar a análise desses dados em um único computador, uma
capacidade de processamento muito grande seria necessária por um longo tempo, e o custo
para realização dessa tarefa poderia inviabilizar o projeto. A utilização de recursos ociosos
espalhados pela internet, de forma gratuita, era talvez uma das poucas soluções disponíveis
que viabilizariam o projeto [Web site SETI@home]. Os diversos resultados obtidos das
análises
realizadas,
e
a
evolução
do
projeto,
podem
ser
conferidos
no
site
http://setiathome.ssl.berkeley.edu/.
O projeto SETI@HOME foi um dos pioneiros na distribuição de tarefas para
processamento distribuído pela internet, e a quantidade de resultados obtidos contribuem para
a análise de vida extra terrestre, alem de possibilitar que diversos usuários anônimos pela
internet possam dar sua contribuição em termos de recursos para o projeto.
2.3 REDES P2P COM INDEXAÇÃO CENTRALIZADA: O NAPSTER
O Napster pode ser considerado um marco na história da internet, especialmente
quando falamos de um assunto tão polêmico como compartilhamento de MP3. Criado
originalmente com este propósito, o Napster permitia a seus usuários a rápida pesquisa de
arquivos .mp3 compartilhados e a troca de mensagens instantâneas entre peers.
Depois de configurada a pasta de compartilhamento de conteúdo, o Napster enviava a
lista de arquivos compartilhados para um repositório central de dados, que era o responsável
também pelo armazenamento e atualização do endereço IP de cada conexão realizada pelo
13
programa. Este repositório central de dados também indica se um determinado usuário está
on-line naquele momento ou não [PARAMESWARAN, M.; SUSARLA, A.; WHINSTON ,
A., 2001].
Essa arquitetura centralizada de indexação de conteúdo foi a grande responsável pela
eficiência da procura de arquivos .mp3 no Napster, pois dessa maneira, os servidores
responsáveis pela indexação, poderiam retornar todos os peers on-line que possuíam um
determinado arquivo em uma busca rápida e precisa. Depois de realizada a busca do conteúdo
desejado, toda a comunicação e troca de informações eram feitas diretamente entre os peers,
sem carga adicional nos servidores de indexação, que atuavam apenas realizando buscas,
autenticando usuários e “apresentando” peers, possibilitando que esses efetuassem a
transferência de dados diretamente da melhor forma possível.
Esta arquitetura centralizada também foi a grande responsável pelo fim do Napster.
Após uma ação judicial, os servidores centrais de indexação de conteúdo foram impedidos de
funcionar, e os peers não podiam mais contar com a busca centralizada e não sabiam mais
quem possuía um determinado conteúdo. Também ficou fácil para as autoridades saberem
quem estava requisitando um determinado tipo de conteúdo, e em pouco tempo, grande parte
das buscas que envolviam conteúdos com direitos autorais estavam censuradas, o que levou
gradativamente a rede Napster ao fim.
2.4 A REDE DESCENTRALIZADA: PROJETO GNUTELLA
14
O aplicativo compartilhador de arquivos GNUTELLA foi desenvolvido em meados de
março de 2000. Sua versão inicial foi desenvolvida por Justin Frankel e Tom Pepper,
criadores do famoso player de arquivos de áudio WINAMP. A empresa criada por eles
chamada NULLSOFT, detentora inicial do WINAMP foi adquirida pela AOL em 1999
[ANDY, O., 2001].
Desenvolvido em apenas 14 dias, o GNUTELLA ficou poucas horas hospedado nos
servidores da AOL, e foi baixado por mais de 10.000 usuários. Imediatamente receosa de
futuras ações judiciais por parte das grandes gravadoras musicais, o software foi retirado do ar
e o projeto encerrado dentro da empresa. Porém, os 10.000 downloads realizados foram
suficientes para a continuidade da rede [ANDY, O., 2001]. Brian Mayland iniciou o processo
de engenharia reversa do software original, continuando a idéia em um projeto open source
com ajuda de diversos outros programadores espalhados pelo mundo. Atualmente diversos
softwares compartilhadores de arquivo utilizam o protocolo de comunicação criado no projeto
GNUTELLA, e assim compartilham a mesma rede.
Por atuarem tanto como clientes quanto servidores, esses softwares são apelidados de
“servents”. Cada servent funciona basicamente como um web server, servindo os conteúdos
compartilhados; e como um browser, pesquisando e requisitando os conteúdos armazenados
distribuidamente nos servents de outros peers. Toda a comunicação realizada pelos peers é
efetuada pela porta 80, utilizando o protocolo HTTP (Hiper Text Transfer Protocol), o mesmo
utilizado pelos web browsers [ANDY, O., 2001].
O objetivo inicial do projeto era desenvolver um aplicativo compartilhador de
arquivos totalmente descentralizado, e que sobrevivesse a qualquer tipo de intervenção. Para
que isso seja possível, a rede formada pelos usuários do GNUTELLA não tem um servidor
15
central de indexação e a busca é realizada ponto a ponto por cada computador participante da
rede, utilizando técnicas como flooding, isto é, enviando consultas para todos os
computadores conhecidos de um peer, e esses computadores enviam a mesma consulta para
todos os seus conhecidos, com objetivo de propagar as consultas para o maior número de
peers conhecidos.
Cada nó nesta rede é responsável por manter a lista de nós conhecidos, buscar novos
peers na rede, e encaminhar cada requisição (Identificada unicamente por uma chave gerada)
para os peers conhecidos, até que algum deles responda avisando que possui o conteúdo
desejado. Neste caso as respostas percorrem o caminho de volta, identificando o peer que
possui o conteúdo. Toda e qualquer requisição de consulta é armazenada em cache, isto é,
armazenada localmente pelos peers para uma futura consulta, evitando que as informações
sejam desperdiçadas e que requisições duplicadas sejam reenviadas. Além disso, somente a
identidade do último peer que encaminhou a requisição é conhecida, garantindo a privacidade
na busca de conteúdo. Somente o conteúdo que fez a requisição sabe que uma determinada
consulta pertence a ele. Para os participantes da rede, não há como distinguir se o peer que
encaminha uma consulta, é realmente o que originou esta consulta ou simplesmente mais um
peer encaminhando a consulta, dando assim a continuidade do processo de pesquisa do
conteúdo requerido [ANDY, O., 2001].
16
Figura 1 - Propagação de busca entre peers na rede GNUTELLA.
Por ser uma rede totalmente descentralizada, é necessário conectar-se a um host
participante da rede para poder ingressá-la. Um cache de host também é fornecido
inicialmente e permite a descoberta e a apresentação de outros peers.
Um dos notórios problemas dos aplicativos que utilizam o protocolo GNUTELLA, é o
seu consumo de banda e a demora na realização de buscas. Isso acontece devido a total
descentralização da rede e a repetição das mensagens de busca enviadas. Cada mensagem de
busca contém um TTL (Time To Live), caracterizado pelo número de saltos máximos (Hops
to Live, HTL) entre peers que a mensagem deve sobreviver na rede. O padrão utilizada no
GNUTELLA é de 256 HTLs para cada busca realizada. A cada peer em que a busca é
encaminhada este valor é decrementado, evitando que uma mensagem seja propagada
infinitamente pela rede [ANDY, O., 2001], [ANDY, O., 2001]. Apesar do consumo de banda
excessivo e da demora na obtenção de resultados, as buscas são sempre efetivas e o conteúdo,
17
caso disponível na rede, quase sempre encontrado. Caso o conteúdo procurado seja
encontrado, toda e qualquer transferência de dados é realizada diretamente entre o peer que
contém o conteúdo e o que iniciou a busca, pois ambos já conhecem os endereços de rede
utilizados, caracterizando uma comunicação totalmente P2P.
Apesar da descentralização da rede GNUTELLA, alguns softwares clientes possuem
algoritmos para análise da rede, permitindo que peers mais capacitados em processamento e
recursos de banda, fiquem no topo da hierarquia em relação aos peers menos favorecidos.
Desta forma conseguimos manter a descentralização da rede, porém de uma forma mais
organizada, otimizando o tempo necessário para propagação de buscas e reduzindo o consumo
de banda (Figura 2). Dos diversos softwares que utilizam a rede GNUTELLA nem todos
implementam esta funcionalidade ainda, dificultando uma análise efetiva da rede formada
[ANDY, O., 2001].
Figura 2 - Rede GNUTELLA organizada por algoritmos de análise de rede. Peers que possuem maior
capacidade de processamento ou maior largura de banda ficam no topo da hierarquia, atuando como
reendereçadores de mensagens e indexadores de conteúdo.
A grande vantagem dessa arquitetura totalmente descentralizada em relação à
abordagem cliente/servidor anterior, é a impossibilidade de se acabar com a rede ou inutilizála caso um dos peers participantes saia da rede por algum motivo. A censura de um
18
determinado conteúdo torna-se praticamente impossível dessa forma, e o anonimato e a
privacidade dos publicadores e compartilhadores de conteúdo são garantidas. Mas se
compararmos a eficiência e a rapidez da busca com a arquitetura cliente/servidor utilizada
pelo Napster veremos que esta última leva uma grande vantagem.
Recentemente alguns usuários da rede GNUTELLA foram processados por gravadoras
que descobriram a sua identidade. Mas como isso foi possível em uma rede descentralizada,
sem um controle central de autenticação? A resposta é bem simples. A rede GNUTELLA trata
todos os nós da rede da mesma forma. Não seria difícil para um nó arbitrário forjar a
publicação de um conteúdo bastante requisitado e descobrir o endereçamento IP dos seus
requisitantes. Apesar da pesquisa de conteúdo não revelar a identidade do peer que iniciou a
requisição, a transferência de dados do conteúdo, caso aconteça, e feita diretamente entre os
peers, permitindo que um deles obtenha o endereço de rede utilizado pelo outro [ANDY, O.,
2001]. Com esses dados em mãos a identificação de um usuário em toda a internet é na
maioria dos casos bem simples, uma vez que cada provedor de acesso mantém o histórico e a
localização física de cada conexão.
Figura 3 - Comparação entre as buscas realizadas na rede Napster (Indexação de conteúdo centralizada) e
na rede GNUTELLA (Busca distribuída por “flooding”).
19
3. INTRODUÇÃO AO JXTA
JXTA (Juxtapose) é um projeto open source de protocolos P2P baseados em
mensagens XML para o desenvolvimento de aplicativos distribuídos, permitindo que qualquer
dispositivo conectado em uma rede, independente de sua plataforma, natureza, ou protocolo
de rede possa interagir, compartilhar recursos, e formar uma rede distribuída, descentralizada
e cooperativa.
O projeto foi iniciado pela Sun Microsystem em abril de 2001 e teve como arquiteto
líder o chefe do departamento de computação da Sun Billy Joe [SUN MICROSYSTEMS,
INC.]. O nome vem de juxtapose, uma referência ao modelo oposto de aplicações P2P em
relação aos modelos tradicionais utilizados como cliente/servidor. JXTA não é uma
linguagem de programação, é uma especificação que tem implementações em diversas
linguagens como C e Java.
O objetivo do JXTA é facilitar o desenvolvimento de aplicativos P2P, encapsulando
funcionalidades e serviços comuns, escondendo a complexidade das implementações para o
desenvolvedor de aplicativos, podendo esse se preocupar somente com a lógica e os detalhes
pertinentes a sua aplicação [SUN MICROSYSTEMS, INC.].
A idéia básica do JXTA é formar uma camada de rede virtual, independente da rede
real utilizada por cada dispositivo, provendo transparência da rede utilizada pelos dispositivos
e permitindo que mesmo dispositivos conectados indiretamente à internet através de um
proxy, ou por um gateway que realiza o NAT (Network Address Translation), ou até mesmo
20
com restrições de um firewall, possam participar da rede oferecendo serviços. Nessa situação
todo o roteamento necessário para a comunicação de peers entre redes distintas é realizado de
forma transparente, utilizando-se de peers intermediários que possam encaminhar as
requisições entre redes. A especificação JXTA foi concebida para ser independente de uma
linguagem específica de programação (como por exemplo C ou Java), plataformas e sistemas
operacionais (como Windows e LINUX), e mesmo dos protocolos de rede utilizados (como
TCP/IP ou Bluetooth) [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.;
HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003]. A forma básica de
comunicação entre os participantes dessa rede é através de mensagens XML padronizadas,
chamadas advertisements, respeitando os protocolos definidos nas especificações definidas no
projeto JXTA. [GONG, Li, 2002].
PeerID
PeerID
PeerID
PeerID
PeerID
PeerID
PeerID
PeerID
Rede Virtual JXTA
Mapeamento Virtual
Rede Física
Peer
Peer
TCP/IP
Peer
Firewall
Peer
HTTP
Peer
Peer
Peer
NAT
Peer
Figura 4 - JXTA forma uma rede virtual, permitindo a comunicação transparente entre peers que
utilizam protocolos diferentes ou pertencem a redes diferentes.
Um dos fatores que contribuem para o sucesso da tecnologia P2P atualmente, e
conseqüentemente do projeto JXTA, é a diversidade de dispositivos tecnológicos presentes
em nossas vidas atualmente. Celulares, PDAs e desktops compartilham muitas informações,
21
mas quase sempre de uma forma indireta, com intermediários, através de servidores e
dependendo de uma rede comum, como a Internet ou uma rede local. Utilizando JXTA
podemos ter esses diversos dispositivos conectados sem a necessidade de uma estrutura
centralizada de rede. O JXTA também permite que a topologia de rede mais adequada para
uma aplicação seja definida por seus criadores, possibilitando o surgimento de novos serviços
e funcionalidades. Cada aplicação possui requisitos de rede que nem sempre se encaixam nos
modelos e arquiteturas tradicionais existentes. Em muitos casos precisamos utilizar mais de
uma arquitetura simultaneamente para suprir os requisitos de uma aplicação, como por
exemplo, utilizar uma comunicação típica cliente/servidor, e em alguns casos específicos
poder comunicar diretamente dois peers sem a necessidade de utilizar um servidor como
intermediário.
Figura 5 - Diversos dispositivos podem compartilhar informações, independente de sua origem ou
protocolo de rede, através da camada de rede virtual oferecida por JXTA.
22
3.1 PRINCIPAIS CONCEITOS DA TECNOLOGIA
O JXTA define algumas abstrações importantes de rede que permitem a formação de
uma camada de rede virtual: Primeiramente um endereço lógico para cada peer é definido em
toda rede, através de um peer ID. Os peers auto-organizam-se em grupos chamados peer
groups, formando domínios virtuais com características pré-definidas.
Os peers são
responsáveis também pela criação de recursos e serviços, como por exemplo os peers groups,
que precisam ser publicados para serem válidos para os outros peers participantes da rede
JXTA. Cada recurso e serviço possue um tipo específico de advertisement. As operações de
bind necessárias em ambientes distribuídos, como traduções de nomes em endereços de rede,
são implementadas por mecanismos denominados resolvers. Finalmente pipes são utilizados
para comunicação entre peers de uma forma transparente [TRAVERSAT, B.; ARORA, A.;
ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER,
B., 2003]. A seguir definiremos as principais abstrações e componentes característicos da rede
JXTA.
3.1.1 JXTA ID
Cada elemento participante da rede recebe um identificador UUID de 128 bits,
garantido sua correta e única identificação na rede [TRAVERSAT, B.; ABDELAZIZ, M.;
DUIGOU, M.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.;
ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL,
E.; YEAGER, B., 2003].
23
3.1.2 ADVERTISEMENTS
Todas as entidades participantes da rede P2P (peers) são representadas por
advertisements. Peers publicam, isto é, disponibilizam dados na rede, mantém um cache e
trocam advertisements para descobrir novos peers e buscar novos recursos na rede. Os
advertisements representam uma abstração de um determinado recurso disponível em uma
rede JXTA. Toda e qualquer publicação e descoberta de objetos participantes na rede JXTA é
feita através de publicação de advertisements específicos [TRAVERSAT, B.; ABDELAZIZ,
M.; DUIGOU, M.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.;
ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL,
E.; YEAGER, B., 2003].
<?xml version=”1.0”?>
<!DOCTYPE jxta:PGA>
<jxta:PGA xmlns:jxta=”http://jxta.org”>
<GID>urn:jxta:jxta-NetGroup</GID>
<MSID>urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000010206</MSID>
<Name>NepPeerGroup</Name>
<Desc>NetPeerGroup by default</Desc>
</jxta:PGA>
Figura 6 - Exemplo de um advertisement para criação de um peer grupo na rede JXTA.
3.1.3 PEERS
Peer é qualquer entidade que possa participar e interagir com a rede, seja ela um
computador, um processo, um processador ou até mesmo um usuário. Para ser considerado
um peer essa entidade deve ao menos entender os protocolos de comunicação básicos
definidos pela tecnologia, como o Peer Resolver Protocol e o EndPoint Router Protocol,
explicados mais adiante neste capítulo [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.;
HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.;
24
ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER,
B., 2003], [SUN MICROSYSTEMS, INC., 2002].
3.1.4 PEER GROUPS
Os peers estão organizados em peer groups. Peers agrupados sob o mesmo grupo tem
algo em comum, como por exemplo, o seu conteúdo compartilhado, e seguem as regras
definidas e atribuídas pelo seu criador. A criação de peer groups e suas regras de utilização
podem ser definidas por qualquer participante da rede JXTA [TRAVERSAT, B.;
ABDELAZIZ, M.; DUIGOU, M.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002],
[TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.;
HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003], [SUN MICROSYSTEMS, INC., 2002].
3.1.5 PIPES
Pipes são canais de comunicação virtuais usados para envio e recebimento de
mensagens entre peers. Pipes não estão associados fisicamente com a localização/endereço de
um peer e são identificados por um pipe ID. Pipes também possibilitam uma comunicação
assíncrona, definindo pipes de entrada e saída. Por não estarem associados com o endereço
físico de um peer, aplicações e serviços que se comunicam através de pipes não são afetadas
pela mudança de localização dos peers e eventuais mudanças de rota que possam acontecer
durante a transmissão de dados. Mensagens são enviadas pelos pipes e recebidas pelos
“ouvintes” registrados neste pipe. Pipes podem restringir o conteúdo a ser trafegado e prover
comunicação segura entre os endPoints [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.;
25
HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.;
ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER,
B., 2003], [SUN MICROSYSTEMS, INC., 2002].
Peer B
Peer C
Pip
e
Peer D
Pipe entre
Peer B e Peer E
Peer A
Peer E
Figura 7 - A Comunicação entre peers é realizada através de pipes.
3.1.6 ENDPOINTS
É o endereço de rede ao qual um peer está localizado. Ao se estabelecer uma conexão
entre peers os pipes se encarregam de saber o endPoint dos participantes, abstraindo os peers
de um endereçamento físico [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.; HUGLY,
J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ,
M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003],
[SUN MICROSYSTEMS, INC., 2002].
3.1.7 JXTA MESSAGES
JXTA Messages são mensagens XML padronizadas, utilizadas para a comunicação
entre os peers. A comunicação é feita enviando e recebendo mensagens. Messages podem ser
de vários tipos, cada um específico para o tipo de conteúdo trafegado, como por exemplo,
26
dados binários em grande quantidade [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.;
HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.;
ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER,
B., 2003], [SUN MICROSYSTEMS, INC., 2002].
3.1.8 RENDEZVOUS PEERS
Rendezvous Peers são peers especiais que indexam informações sobre outros peers
que ele tem conhecimento. Sendo assim, este peer pode ajudar na busca por um peer
específico ou no roteamento de mensagens propagadas na rede. Caso não haja nenhuma
informação disponível em seu índice, a requisição é passada adiante para outro rendezvous
peer, e assim por diante. Rendezvous peers são de fundamental importância na rede para
diminuir o tráfego de mensagens enviadas e para otimizar o processo de busca de recursos,
evitando que a busca propague-se pela a rede inteira. A publicação de um Rendezvous peers é
feita pela publicação de um advertisements específico para este propósito. [TRAVERSAT, B.;
ABDELAZIZ, M.; DUIGOU, M.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2002],
[TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.;
HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003].
27
Super-Peers
Adv
Rdv 2
Rdv 1
Index
Adv
Peer A Índice
Adv
Index
Propagação(2)
Resposta(3)
Peer B
Adv
Query(1)
Resposta(4)
Rede Virtual JXTA
Rede Física
Peer 2
Peer 1
Firewall
NAT
Figura 8 - Peers rendezvouz otimizam a procura de advertisements na rede, reduzindo o número de
mensagens propagadas, funcionando muitas vezes como um atalho para encontrar os recursos disponíveis
na rede.
3.1.9 RELAY PEERS
Muito dos peers participantes da rede JXTA possuem conexões temporárias, e
freqüentemente tem o acesso direto à internet restrito por um firewall ou por uma conexão a
ser realizada através de um NAT. Para conseguir acesso aos recursos da rede JXTA, relay
peers podem efetuar o roteamento de mensagens entre peers, possibilitando que ambos se
comuniquem. Relay peers ajudam o roteamento de mensagens entre peers, indicando os
passos necessários (Hops) para que uma determinada mensagem atinja seu destino. Qualquer
peer, desde que tenha as devidas permissões em seu grupo, pode tornar-se um relay peer. A
publicação de Relay peers é feita pela publicação de um advertisement específico para esta
finalidade [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD,
C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003].
28
Super-Peers
Relay D
Relay C
Peer A
Relay
Peer B
Resposta(4)
Rede Virtual JXTA
Rede Física
Peer C
Envio
Pulling
NAT
Envio
Firewall
Pulling
HTTP
Figura 9 - Relay peers possibilitam a comunicação entre peers pertencentes a redes distintas ou com
restrições de um firewall ou NAT.
3.2 PROTOCOLOS JXTA
O JXTA define diversos protocolos, sendo cada um deles responsável por executar
uma tarefa específica na rede P2P como, por exemplo, realizar o roteamento de mensagens e
possibilitar a comunicação entre peers. Cada protocolo é definido por uma ou mais mensagens
em formato XML, trocadas entre os peers participantes da rede. Atualmente estão definidos
seis protocolos com suas funcionalidades explicadas a seguir [TRAVERSAT, B.; ARORA,
A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.;
YEAGER, B., 2003], [SUN MICROSYSTEMS, INC., 2002]:
29
3.2.1 PEER DISCOVERY PROTOCOL (PDP)
Este protocolo habilita um peer a procurar advertisements do tipo peers, peers groups,
pipes e conteúdo, além de enviar os advertisements publicados pelo próprio peer para o
restante da rede. Este é o principal canal de comunicação do peer com o restante da rede. A
descoberta de novos peers na rede, pode ser feita explicitamente, especificando o UUID do
peer ou do peer group desejado, neste último caso retornando todos os peers pertencentes ao
grupo. A descoberta de todos os peers groups também é possível [TRAVERSAT, B.;
ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL,
E.; YEAGER, B., 2003], [SUN MICROSYSTEMS, INC., 2002].
Figura 10 - XML Schema que define os elementos de uma Discovery Query.
<Type>
Deve conter o tipo de advertisement que está sendo enviado:
30
0 - Peer Advertisements
1 - Peergroup Advertisements
2 - Qualquer tipo de advertisement
<Threshold>
Deve conter o número máximo de respostas que um peer deve enviar ao receber este
advertisement.
<PeerAdv>
O conteúdo xml do advertisement específico que deve ser enviado.
<Attribute>, <Value>
Elementos podem ser definidos e adicionados ao advertisement a ser enviado. Dessa
forma, outros peers podem procurar por um advertisement específico, contendo um
elemento correspondente ao definido em <Attribute> e também a um valor
específicado em <Value>.
3.2.2 PEER RESOLVER PROTOCOL (PRP)
O PRP habilita um peer a enviar e receber queries para procura de peers, peers groups,
pipes e outras informações na rede. Cada query é associada a um Handler, responsável por
processar a mensagem e aguardar as respostas resultantes da query a serem enviadas pelos
peers. Peers que provêem compartilhamento de arquivos podem oferecer uma busca avançada
de seu repositório de dados para os outros peers [TRAVERSAT, B.; ARORA, A.;
ABDELAZIZ, M.; DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER,
B., 2003], [SUN MICROSYSTEMS, INC., 2002].
31
Figura 11 - XML Schema para uma Resolver Query, que deve ser enviada a um Handler específico
definido na rede JXTA. As respostas, caso disponíveis, serão enviadas seguindo as especificações do
Response Query Schema.
<jxta:Cred>
Credêncial do peer que envia a query.
<HandlerName>
Deve conter uma string especificando o Handler de destino que receberá esta query.
<SrcPeerID>
Deve conter o id do peer que originou a query no formato URN.
<QueryID>
Deve conter o id associado a esta query para futuramente identificar as respostas
recebidas.
<HC>
Indica o número de peers que esta query já percorreu. A cada peer que encaminha esta
query, este valor deve ser incrementado.
<Query>
Deve conter a query a ser enviada.
32
3.2.3 PEER INFORMATION PROTOCOL (PIP)
Responsável por obter informações de outros peers, como seu estado atual, tempo de
resposta, utilização de recursos e tráfego atual. Podemos enviar uma mensagem de ping e
saber se o peer ainda continua na rede ou não. Utiliza o Peer Resolver Protocol para enviar e
propagar as requisições de informação [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.;
DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003], [SUN
MICROSYSTEMS, INC., 2002].
Figura 12 - XML Schema definindo os elementos necessários para o envio de queries para obtenção de
informações de outros peers.
<sourcePid>
Contém o peer id do peer que originou a query.
<targetPid>
Contém o peer id do peer que se quer mais informações.
<request>
Deve contér o tipo de resposta que se quer obter , como por exemplo, o número de
Hops necessários para se comunicar com o peer.
33
3.2.4 RENDEZVOUS PROTOCOL (RVP)
Peers podem se tornar peers do tipo Rendezvous, indexando advertisements do grupo
a que pertence e propagando mensagens para os ouvintes (Listeners) que estão registrados
nele. Este protocolo controla a propagação de mensagens dos peers Rendezvous para os peers
que pertencem ao mesmo grupo [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.;
DUIGOU, M.; HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003].
Figura 13 - XML Schema definindo os elementos necessários para publicação de um Rendezvous
Advertisement, transformando um determinado peer como Rendezvous do grupo a que ele pertence.
<Name>
Pode conter um nome opcional associado a este rendezvous peer.
<RdvGroupId>
Deve conter o ID do PeerGroup que este peer se tornará um rendezvous peer.
<RdvPeerId>
Deve conter o ID do Peer que se tornará um rendezvous peer.
3.2.5 PIPE BINDING PROTOCOL (PBP)
Protocolo responsável por realizar a conexão de um peer com um ou mais peers.
34
Para cada peer destino que a conexão virtual é estabelecida, um pipe de entrada e saída é
aberto (isto é, é realizado um “bind”), permitindo assim comunicação assíncrona entre os
participantes. Utiliza o Peer Resolver Protocol para enviar e propagar a requisição de bind dos
pipes [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.; HUGLY, J.; POUYOUL, E.;
YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.;
HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003].
Figura 14 - XML Schema definindo os elementos necessários para a criação de um Pipe Advertisement.
<Id>
Deve conter um identificador único para o pipe.
<Type>
Indica o tipo de pipe que está sendo publicado:
JxtaUnicast - Pipe não confiável, não garante a entrega do contéudo, pode entregar o
conteúdo mais de uma vez e não garante a ordem da entrega de conteúdo.
JxtaUnicastSecure – Fornece as mesmas funcionalidades do tipo JxtaUnicast, porém
permite comunicação segura, tendo o seu contéudo criptografado.
JxtaPropagate – Pipe de difusão, utilizado para o envio de mensagens de um para
muitos (one-to-many) pipes.
35
<Name>
Elemento opcional que pode ser adicionado ao advertisement, indicando um nome não
único, facilitando a sua identificação na rede JXTA.
3.2.6 ENDPOINT ROUTING PROTOCOL (ERP)
Protocolo responsável por informar a rota para comunicação entre dois peers distintos
quando uma conexão direta não é possível entre ele. A comunicação direta não será possível
quando dois peers utilizarem redes de protocolos diferentes ou quando entre eles há um
firewall ou a conexão é realizada por NAT. Neste caso o Endpoint Routing Protocol informa a
rota necessária, indicando os gateways necessários para realizar a conexão. Caso a rota entre
dois peers mude, ou a topologia da rede mude por qualquer motivo, este protocolo será
utilizado para indicar a nova rota de comunicação entre eles.
Qualquer peer pode ser um roteador deste tipo implementando o Endpoint Routing
Protocol [TRAVERSAT, B.; ABDELAZIZ, M.; DUIGOU, M.; HUGLY, J.; POUYOUL, E.;
YEAGER, B., 2002], [TRAVERSAT, B.; ARORA, A.; ABDELAZIZ, M.; DUIGOU, M.;
HAYWOOD, C.; HUGLY, J.; POUYOUL, E.; YEAGER, B., 2003].
36
Figura 15 - XML Schema definindo os elementos necessários para o envio de Advertisements, contendo
informações de rota para um determinado peer.
<DstPID>
Deve conter o Peer ID do peer que as informações de rota estão sendo descritas.
<APA>
Contém uma lista de endereço associados com o peer informado.
<Hops>
Contém uma coleção de Advertisements descrevendo uma rota para o peer indicado
em <DstPID>
37
Protocolos de
Serviços
Padrão
(opcional)
Protocolo
Peer Discovery
Protocolo
Pipe Binding
Protocolo
Peer Information
Protocolo
Peer Resolver
Protocolo
Rendezvous
Protocolos
Core
(obrigatório)
Protocolo
Endpoint Routing
Figura 16 - Protocolos opcionais e obrigatórios definidos na tecnologia JXTA.
Serviço PeerGroup
Serviço
Discovery
Serviço
Pipe
Serviço
Resolver
Serviço
Membership
SRDI
Serviço
Rendezvous
Serviço
Peer Info
RPV
Walker
Serviço Endpoint
Mensageiro Virtual
Advertisements
XML
Parser
Mensagem
ID
Gerente de
Cache Index
Relay
Transporte
HTTP
Transporte
TCP/IP
Router
Transporte
TLS
Figura 17 - Referência de Implementação JXTA na plataforma Java 2 Standard Edition.
38
4. JXTA SHELL
Uma aplicação SHELL permite a digitação e execução de comandos em forma de
textos, exibindo o resultado da execução dos comandos para o usuário. Uma das principais
aplicações oferecidas para plataforma JXTA atualmente é o JXTA shell. O JXTA shell, é um
ambiente que através de comandos simples permite explorar a rede, adicionando peers,
peersgroups e enviar qualquer tipo de advertisements, sem a necessidade da utilização de uma
linguagem de programação [KRISHNAN, N., 2003].
Para aqueles que já conhecem o básico do shell de qualquer sistema operacional do
tipo UNIX like (UNIX, LINUX, e derivados), encontramos diversas semelhanças neste
aplicativo, além de muitos comandos com a mesma funcionalidade, como mostramos a seguir.
Para instalar o JXTA Shell, basta realizar o download dos arquivos necessários em
http://download.jxta.org/easyinstall/install.html. A instalação é simples, bastando seguir as
instruções disponibilizadas na página de download.
Além do JXTA shell, a instalação básica disponibiliza uma aplicação chamada
InstantP2P, na qual podemos trocar mensagens instantâneas entre peers, realizar sessões de
chat, compartilhar e pesquisar arquivos compartilhados pelos peers na rede. Tanto o JXTA
shell como o InstantP2P são aplicações codificadas em Java. Diversas API´s (Application
Program Interface) são disponibilizadas, e tarefas como publicação de advertisements,
compartilhamento de arquivos e comunicação entre peers podem ser implementadas para
construção de novos aplicativos.
39
4.1 CONFIGURAÇÃO INICIAL JXTA SHELL
Depois de realizada a instalação, deve-se realizar as configurações básicas e de
segurança de ambas as aplicações. Todas as informações relativas às configurações da
aplicação, bem como o cache de informações da rede realizado, é armazenado no diretório de
instalação escolhido para aplicação.
Depois de instalado, basta iniciar o shell pelo arquivo shell.bat, disponibilizado dentro
da pasta shell contida no diretório escolhido para instalação. Caso o sistema operacional
utilizado seja o Microsoft Windows, uma pasta no menu iniciar estará disponível, contendo os
atalhos correspondentes a cada aplicação. Ao acessar pela primeira vez ambas aplicações,
acessaremos automaticamente as telas de configuração da rede. Nessa tela (Figura 18)
podemos verificar quatro botões correspondentes aos tipos de configuração. Para
configuração utilização inicial siga os passos abaixo [KRISHNAN, N., 2003], [SUN
MICROSYSTEMS, INC., 2001], [OAKS, S.; TRAVERSAT, B.; GONG, Li.]:
1 - Clique no botão nomeado "basic" e preecha a configuração básica, informando o
nome que será identificado o seu peer na rede. Caso sua conexão seja feita por um servidor
proxy é necessário informar o endereço utilizado.
40
Figura 18 - Escolhendo o nome do peer que será identificado na rede JXTA.
2 - Clique no último botão nomeado "security". Escolha um nome de usuário e uma
senha, que serão utilizadas posteriormente para acesso ao shell e a rede JXTA. Essa será a
identificação de seu peer na rede.
Figura 19 - Escolhendo o nome de usuário e senha, dados que são necessários a cada vez que o shell é
iniciado.
41
3 – Clique no botão nomeado rendezvous/relays. Clique no botão “download relay and
rendezvous lists”. Marque a opção “use a relay”.
Figura 20 - Recuperando os peers que serão utilizados como relay e rendezvous.
Depois de realizada a configuração, o shell estará pronto para ser utilizado. Ao
visualizar o prompt "JXTA>", podemos digitar qualquer comando válido, que o mesmo será
executado e sua resposta, caso disponível, será exibida na tela.
42
Figura 21 - Tela inicial do JXTA shell.
4.2 COMANDOS JXTA SHELL
Atualmente estão implementados mais de 40 comandos no JXTA Shell [KRISHNAN,
N., 2003], [SUN MICROSYSTEMS, INC., 2001]. A seguir explicaremos os principais
comandos aproveitando para conhecer a rede JXTA e visualizar alguns conceitos
anteriormente explicados.
4.2.1 MAN
Lista todos os comandos disponíveis para serem utilizados. Similar ao comando man
do UNIX. Pode ser utilizado para obter ajuda sobre um comando específico. Ex: man cat
43
4.2.2 PEERCONFIG
Inicia a tela de configuração do Shell novamente na próxima execução do programa.
4.2.3 RDVSTATUS
Indica quais são os peers do tipo rendezvous que estamos conectados. Precisamos
estar conectados pelo menos em um rendezvous peer para conhecer o restante da rede.
4.2.4 ENV
Lista todas as variáveis usados pelo shell. Por padrão são definidas sete variáveis.
4.2.5 CAT
Exibe o conteúdo de uma variável definida pelo shell. Similar ao comando cat
utilizado no UNIX. Esta é a forma básica de exibir o conteúdo de variáveis e objetos criados
no shell.
4.2.6 GREP
Procura uma string específica em uma variável. Similar ao comando grep do UNIX.
44
4.2.7 HISTORY
Lista o histórico de comandos digitados anteriormente
4.2.8 VERSION
Indica a versão atual do shell.
4.2.9 EXIT
Encerra a sessão atual do shell.
4.2.10 GROUPS
Lista todos os grupos que o shell tem conhecimento em seu cache. Para procurar
novos groups na rede devemos enviar o comando groups –r. Para atualizar as informações
mantidas no cache, devemos enviar o comando groups –f. Para listar as informações dos
grupos conhecidos, podemos utilizar a opção –l
45
Figura 22 - Depois de executado o comando groups -r para a descoberta de novos grupos, exibimos os
grupos encontrados com o comando groups.
4.2.11 PEERS
Lista todos os peers que o shell tem conhecimento em seu cache. Da mesma forma que
o comando anterior, podemos descobrir novos peers com o comando peers –r, e atualizar as
informações armazenadas em cache com o comando peers –f. Para listar as informações dos
peers conhecidos devemos utilizar a opção –l.
46
Figura 23 - Resultado da execução do comando peers.
4.2.12 WHOAMI
Indica as informações do seu peer, exibindo os endereços TCP e HTTP utilizados além
dos identificadores(UUID) atribuídos ao peer. Utilizado com a opção –g informa em qual
grupo o peer pertence.
Figura 24 - Resultado da exibição do comando whoami e whoami –g executados no JXTA shell.
4.3 CRIANDO UM GRUPO NA REDE JXTA
Para criar um grupo na rede JXTA, precisamos primeiramente criar o Advertisement
correspondente, e depois publicá-lo para os outros componentes da rede. Segue abaixo um
47
exemplo da criação do Advertisement para grupo com o comando mkadv [KRISHNAN, N.,
2003], [SUN MICROSYSTEMS, INC., 2001], [OAKS, S.; TRAVERSAT, B.; GONG, Li].
JXTA> grupoAdv=mkadv –g grupoteste
Para visualizar o conteúdo do advertisement criado podemos exibir o conteúdo da
variável grupoAdv criada com o comando abaixo:
JXTA> cat grupoAdv
Figura 25 - Ao exibir o advertisement criado, podemos verificar os identificadores atribuídos para a
mensagem (<MSID>) e para o grupo (<GID>).
Basta agora criarmos o grupo associando o advertisement a ser publicado com o
comando mkpgrp
JXTA> mkpgrp –d grupoAdv
Com o grupo criado podemos visualiza-lo após enviar o comando groups –r e
posteriormente groups:
JXTA> groups –r
JXTA> groups
Figura 26 - Resultado da criação do grupo definido anteriormente, sendo listado após a execução do
comando groups.
48
Por default todos os peers pertencem ao NetPeerGroup, que é o grupo no topo da
hierarquia JXTA. Cada peer pode juntar-se a qualquer grupo JXTA existente na rede desde
que possua permissão para integrar o mesmo. Em nosso caso nenhuma forma de autenticação
foi especificada. Para fazer parte do grupo criado anteriormente usaremos o comando join:
JXTA> join grupoteste
Como somos o criador do grupo, podemos especificar o nome dele diretamente no
comando join. Para ingressar outros grupos devemos enviar o comando na seguinte forma:
JXTA> join –d group1
Ao listarmos os grupos com o comando groups os mesmos serão exibidos inicialmente
com o nome seqüencial group1,group2 e assim por diante. Para ingressarmos no grupo
remoto, basta informar o “indíce” atribuído para o grupo. No caso acima estamos acessando o
primeiro grupo listado.
Para deixarmos o grupo basta executar o comando leave.
Figura 27 - Por padrão todos os peers pertencem ao NetPeerGroup, como pode ser verificado pela
exibição do comando whoami -g ao iniciar o JXTA shell. Após requisitar a entrada no grupo 2,
executamos novamente whoami -g, que exibe as informações do grupo atual.
49
4.4 CONVERSANDO NA REDE JXTA
Através do comando talk é possível o envio de mensagens instantâneas para os peers
conectados na rede JXTA. Basicamente podemos enviar mensagens com ou sem segurança,
isto é, podemos enviar mensagens criptografadas aumentando a privacidade e a segurança da
comunicação [KRISHNAN, N., 2003], [OAKS, S.; TRAVERSAT, B.; GONG, Li].
Primeiramente precisamos iniciar o comando talk fornecendo um nick:
JXTA> talk –register meunick
O comando acima basicamente encapsula a criação de um advertisement para os pipes
que serão responsáveis pelo envio e recebimento de mensagens.
Depois de registrado no serviço talk e escolhido um nick precisamos efetuar o login
para iniciar a conversação:
JXTA> talk –login meunick
Após o login qualquer mensagem enviada por um peer remoto será exibida no console.
O comando de login inicia o pipe de entrada, disponibilizando uma thread para verificar a
chegada de conteúdo, permitindo a exibição das mensagens recebidas instantaneamente.
Para procurar outros peers disponíveis para conversação, podemos utilizar o comando
talk-search. Abaixo segue um exemplo para o envio de uma mensagem para você mesmo:
JXTA> talk –u meunick meunick
50
Após executar o comando acima basta digitar a mensagem e terminá-la com um ponto
final “.”.
O comando talk facilita a comunicação na rede evitando a necessidade da criação de
advertisements e outros objetos que permitem a comunicação. Caso seja necessário podemos
criar os advertisements, pipes e enviar mensagens para os peers com os comandos disponíveis
no Shell [KRISHNAN, N., 2003], [OAKS, S.; TRAVERSAT, B.; GONG, Li].
Figura 28 - Exemplo de dois peers (Peer1 e Peer2) conversando na rede JXTA com o comando talk.
51
4.5 CACHING DE ADVERTISEMENTS
Na rede JXTA peers são descobertos freqüentemente, porém não podemos garantir
que sua conexão está disponível em um outro momento. Esses peers são transientes, e é por
isso que as redes P2P são chamadas de redes não confiáveis [KRISHNAN, N., 2003].
Todos as informações e advertisements descobertos pelo shell ficam armazenadas no
diretório ./cm, dentro da pasta escolhida para a instalação do JXTA. A cada reinício o shell
recupera as informações obtidas anteriormente. Muitas dessas informações armazenadas
estarão desatualizadas e em muitos casos inválidas.
Para atualizar as informações armazenadas em cache, os comandos peers e groups
aceitam um argumento –f, realizando uma atualização (flush) das informações quando
solicitado.
Essa técnica de cache é fundamental para diminuir o tráfego de mensagens
redundantes na rede. Para evitar que os advertisements fiquem armazenados por um longo
período no cache das aplicações, um TTL(Time To Live) é especificado junto com o seu
envio, definindo assim o tempo de vida de cada recurso criado na rede JXTA. Essa
característica é fundamental para a auto-suficiência e atualização da rede sem um controle
centralizado [OAKS, S.; TRAVERSAT, B.; GONG, Li.].
52
O cache de advertisements, apesar de padrão nas API’s de binding JXTA, não é
obrigatório e nem padronizado. Cada aplicação escolhe a melhor forma de realizá-lo de
acordo com seus recursos disponíveis [OAKS, S.; TRAVERSAT, B.; GONG, Li].
Figura 29 - Caching de advertisements realizado pela aplicação JXTA Shell. Ao executar qualquer
aplicação JXTA, um diretório “\.jxta\cm\“ será criado automaticamente no diretório em que a aplicação
está sendo executada. Nesta figura podemos observar os diversos tipos de advertisements (PeerGroups,
Peers, Messages) armazenados após a primeira execução da aplicação. Ao abrir um dos arquivos em um
editor de texto, podemos verificar o conteúdo XML dos advertisements.
4.6 A IMPORTÂNCIA DOS PIPES
A descentralização e a natural distribuição dos peers na rede JXTA, torna-se um
desafio para a realização de uma comunicação e transferência de dados efetiva. Cada peer
poderá juntar-se a rede em apenas alguns momentos, e ainda assim sua conexão poderá ser
transiente, além de ser realizada em redes que utilizam protocolos diferentes. O principal
objetivo para os desenvolvedores de soluções P2P, é garantir o sucesso na comunicação dos
peers independente da forma de conexão e do protocolo de rede utilizado. Além disso, os
peers podem estar conectados a rede através de um NAT, ou sofrendo restrições na
transmissão de dados por um firewall. Uma das principais soluções adotadas por JXTA para
enfrentar essas dificuldades são a utilização de pipes [OAKS, S.; TRAVERSAT, B.; GONG,
Li].
Para realizar a comunicação entre dois peers em uma rede transiente, heterogênea e
com as dificuldades listadas anteriormente, precisamos realizar várias conexões
53
intermediárias, e utilizar os atalhos e peers roteadores participantes da rede. Por esse motivo,
as conexões realizadas por pipes são comumente referidas como conexões virtuais ou lógicas
[OAKS, S.; TRAVERSAT, B.; GONG, Li]. Essa é uma importante abstração que permite a
efetividade da comunicação e transmissão de dados entre os peers. A forma como é realizada
a comunicação entre pipes, permite que as aplicações se adaptem com as constantes falhas da
rede, requisito fundamental para redes P2P.
Uma das principais características dos pipes é a transparência de rede que eles
permitem para o desenvolvedor de aplicativos. Para realizar a comunicação entre dois pipes,
precisamos apenas de sua identificação na rede JXTA, e todos os processos intermediários
necessários serão executados sempre escolhendo as melhores alternativas e soluções. Em uma
rede local, por exemplo, a melhor forma de se estabelecer comunicação entre dois peers pode
ser utilizando TCP/IP. Esta solução talvez não seja válida para peers que precisam se
comunicar através de um firewall ou pertençam a redes diferentes, e conseqüentemente
utilizarão HTTP para efetuar a transmissão de dados [OAKS, S.; TRAVERSAT, B.; GONG,
Li]. A abstração na forma como é realizada a comunicação entre peers, permitem aos pipes a
utilização dos protocolos TCP/IP e HTTP para a transmissão de dados, de uma forma
transparente para o desenvolvedor de aplicações. A utilização do protocolo HTTP ocorre
quando é necessária a comunicação de peers pertencentes a redes distintas, ou quando um dos
peers tem restrições impostas pela rede utilizada, como por exemplo, um firewall.
A comunicação básica entre pipes é unidirecional e assíncrona, e não há garantia de
que a mensagem será enviada. Porém outros tipos de conexão estão disponíveis e podem ser
utilizadas [OAKS, S.; TRAVERSAT, B.; GONG, Li]:
· Síncrona request/response: Após o envio de uma mensagem uma resposta é enviada
pelo receptor.
54
· Publish/Subscribe: Um pipe do tipo EndPoint registra-se como ouvinte (Subscribe)
para as mensagens enviadas por um publicador(Publish).
· Bulk data transfer: Uma conexão confiável para a transferência de dados binários.
· Streaming: Realiza uma transferência eficiente de dados através de um canal com
controle de fluxo.
Figura 30 - Tipos de pipes que podem ser utilizados para comunicação entre peers.
55
5. ESTUDO DE CASO: CHAT P2P DESCENTRALIZADO
5.1 CHAT CLIENTE/SERVIDOR X CHAT P2P
Chats são aplicações que permitem a troca de mensagens de texto entre uma ou mais
pessoas, e são comumente encontradas em diversos sites da web. A maioria das salas de chat
necessitam de um servidor central para que os clientes possam se conectar e receber novas
mensagens. Ao estabelecer uma conexão com esse servidor central, qualquer nova mensagem
disponível será enviada para o usuário, que recebe todas as mensagens enviada pelos outros
participantes da sala. Toda e qualquer comunicação realizada entre os peers nesta arquitetura
tem que necessariamente passar por este servidor centralizado, que encarrega-se de enviar a
mensagem até o seu correto destino.
Essa arquitetura, apesar de suas peculiaridades, é tipicamente cliente/servidor, e o seu
funcionamento é ideal em muitos casos. Os benefícios oferecidos por uma aplicação
cliente/servidor são diversos, porém muitas desvantagens encontradas nesta arquitetura são
cruciais para outros tipos de aplicação.
O que aconteceria com nossa aplicação de chat se houvesse uma falha neste servidor
centralizado, ou até mesmo na infra-estrutura que conecta o servidor com os diversos
clientes? Quantos clientes simultâneos essa arquitetura é capaz de suportar? Qual o custo para
manter esta aplicação o mais redundante e confiável possível? Mesmo com os avanços das
tecnologias para aplicações de missão crítica qualquer indisponibilidade neste servidor
significa a perda da conexão de muitos usuários, e em muitos casos os custos envolvidos para
56
manter uma alta disponibilidade podem inviabilizar o projeto. No caso de uma aplicação de
chat, geralmente com o objetivo de puro entretenimento, esta talvez não seja uma questão
primordial, porém para aplicações de leilões on-line e negociação em tempo real esta é uma
questão crucial. A arquitetura utilizada para a colaboração e publicação de informações nestas
aplicações é basicamente a mesma utilizada por um chat, logicamente com inúmeras
especificidades que estão além do escopo de nossa aplicação case.
Uma alternativa para o atual modelo cliente/servidor é a comunicação totalmente P2P
entre os participantes. A comunicação neste caso muda radicalmente e passa a ser totalmente
descentralizada. Este modelo de comunicação oferece algumas vantagens, como por exemplo,
uma maior tolerância à falhas. Qualquer peer que tenha problemas na sua conexão com a rede,
não prejudicará os peers restantes, não comprometendo o funcionamento total da aplicação.
Em nossa aplicação, temos ainda a vantagem oferecida por JXTA de comunicar
transparentemente dispositivos pertencentes a redes diferentes, sem nos preocupar qual o
protocolo utilizado, ou qual a melhor rota para realizar a conexão entre eles. Esta
transparência é uma grande funcionalidade oferecida pela tecnologia, e a adição de novas
API´s para outras linguagens, além do Java, contribuirão muito para o crescimento da rede e o
aperfeiçoamento do JXTA.
A principal desvantagem na utilização de uma arquitetura totalmente P2P para uma
aplicação de chat é a quantidade de banda utilizada pelos peers para realizar a comunicação
com todos os outros participantes da rede quando necessário. No caso de enviarmos uma
mensagem para todos os integrantes de uma sala ocupada por 40 usuários, serão necessárias
39 conexões, sendo uma conexão aberta para cada usuário pertencente à sala com exceção do
próprio usuário, e a mesma mensagem será enviada repetidamente para cada usuário.
57
Figura 31 - Chat utilizando arquitetura P2P. Em uma sala contendo N peers serão necessárias N-1
conexões para enviar a mesma mensagem para todos os participantes da rede. Neste caso específico, o
consumo de banda entre os peers será maior, porém não precisamos de um servidor central replicando as
mensagens, o que limita o número de usuários simultaneamente conectados.
Figura 32 - Chat utilizando arquitetura Cliente x Servidor. Para cada cliente, a conexão é estabelecida
apenas uma vez com o servidor, que replica as mensagens entre os outros usuários conectados. O consumo
de banda no servidor e a quantidade de recursos necessários aumentam proporcionalmente ao número de
usuários conectados. Para os peers, o consumo de banda e recursos necessários para utilizar a aplicação
são mínimos, porém qualquer falha no servidor compromete o funcionamento de todos os clientes.
5.2 ARQUITETURA HÍBRIDA CLIENTE/SERVIDOR E P2P
Uma alternativa para minimizar os impactos negativos, tanto da arquitetura P2P
quanto da arquitetura cliente/servidor, é a utilização de uma arquitetura híbrida, isto é, uma
arquitetura que utilize os modelos cliente/servidor e P2P,
aproveitando as vantagens
oferecidas por cada modelo.
A grande diferença desse modelo para a aplicação aqui apresentada, é no envio de
mensagens para todos os usuários de uma sala. Como visto anteriormente, para replicar uma
mensagem enviada para todos os participantes da sala, é necessário que se abra uma conexão
para cada peer individualmente, enviando a mesma mensagem para cada um deles
repetidamente.
58
Utilizando uma arquitetura híbrida, poderíamos manter esta funcionalidade,
aproveitando as vantagens oferecidas pelo modelo cliente/servidor. Neste caso elegemos um
ou mais peers na rede JXTA para exercer a funcionalidade de um servidor, e seria de
responsabilidade deste peer replicar as mensagens para todos os participantes do chat. A única
restrição para essa escolha, é que este peer possa se comunicar com os demais sem nenhuma
restrição. Esse peer poderia ser escolhido segundo determinados critérios de recursos, como
por exemplo, o peer com a melhor conexão em termos de velocidade de rede ou poder de
processamento. Caso um peer deseje enviar uma mensagem exclusivamente para outro peer,
ou mesmo para poucos peers, este poderia realizar a conexão diretamente, sem a necessidade
de enviar esta mensagem para o nosso servidor. Sendo assim, os recursos de banda também
seriam otimizados em comparação ao modelo cliente/servidor, pois utilizando uma arquitetura
híbrida, somente as mensagens destinadas a todos os usuários da sala passariam pelo controle
centralizado.
Figura 33 - Chat utilizando arquitetura híbrida P2P e cliente/servidor. A comunicação direta entre os
peers é freqüentemente utilizada, sendo o servidor necessário apenas quando uma mensagem para todos
os peers é enviada. Dessa forma utilizamos o melhor fornecido por cada arquitetura.
Este capítulo demonstra como foi desenvolvida uma aplicação de chat totalmente P2P,
utilizando as API´s JXTA existentes para java.
Os códigos fontes desta aplicação encontram-se documentados no apêndice A, e os
arquivos, compilados e pronto para serem executados, podem ser obtidos no site
http://www34.brinkster.com/mackjxta, juntamente com as bibliotecas necessárias para
execução do programa.
59
Para executar a aplicação é necessário ter instalado na máquina alguma versão recente
do JRE (Java Runtime Enviroment), que pode ser obtida gratuitamente no site
http://www.java.sun.com.
A aplicação de chat desenvolvida neste estudo tem como objetivo demonstrar os
recursos da plataforma JXTA, além das principais API`s java utilizadas para construção de
aplicativos P2P. O funcionamento da aplicação é baseado no envio de mensagens simples de
texto para todos os participantes do chat, é contém uma área que possibilita a exibição das
novas mensagens enviadas.
A arquitetura de comunicação utilizada é P2P, totalmente descentralizada, sem a necessidade
de um servidor central que replique as mensagens para todos os participantes do chat.
Qualquer novo usuário que realizar o login na aplicação de chat, terá sua entrada notificada
para os outros participantes através da publicação de um advertisement, definido
especificamente para esta aplicação. A descoberta de novos usuários, bem como a verificação
se todos os participantes do chat ainda estão disponíveis, é feita periodicamente por cada
programa cliente. O envio de mensagens só é possível para todos os participantes do chat, não
sendo possível o envio de mensagens reservadas nem direcionadas apenas para um usuário.
5.3 EXECUTANDO A APLICAÇÃO
Depois de instalado e configurado o JRE devidamente, basta descompactar o arquivo
.zip disponibilizado em qualquer diretório. Para executar a aplicação, execute o arquivo
chat.bat, localizado na raiz do diretório onde os arquivos foram descompactados.
60
5.4 CONFIGURANDO O AMBIENTE JXTA
Ao acessar a aplicação pela primeira vez, a configuração básica para acesso a rede
JXTA será requisitada. Verifique as configurações realizadas na secção “Configuração Inicial
JXTA Shell” no capítulo JXTA shell.
5.5 ANALISANDO O CÓDIGO FONTE
A aplicação é construída pela compilação das seguintes classes Java:
Tabela 1 – Classes utilizadas para implementação da aplicação de chat.
Figura 34 – Diagrama UML de classes para a aplicação de chat.
Figura 35 – Diagrama de sequência para as classes Java da aplicação de chat.
Outros dois arquivos, chat.log e logo.jpg, também compõe a aplicação, porém não
contém nenhum código Java , e são apenas arquivos auxiliares para o funcionamento do chat.
61
O arquivo chat.log pode ser analisado para detectar eventuais erros da aplicação, bem como o
resultado de cada ação realizada.
As classes chat.ChatLoginFrame e chat.ChatFrame realizam apenas tarefas simples,
como a escolha do apelido (nick) utilizado, e a exibição de mensagens para o usuário.
Figura 36 - Tela de boas-vindas do Chat
Figura 37 - Tela de conversas do Chat (Peer1)
Figura 38 - Tela de conversas do Chat (Peer2)
5.6 CLASSE CHAT.CHATAPP.JAVA
Ao executar o método main desta classe, instanciaremos um objeto representando ela
própria, e executaremos o método startJxta(), dando início a rede JXTA.
10
20
public static void main(String args[]){
ChatApp chat=new ChatApp();
62
30
40
chat.startJxta();
}
Exemplo 1 – Após executar o construtor da aplicação, a plataforma JXTA é iniciada.
O método startJxta() tem como principal objetivo inicializar o peer atual na rede
JXTA. Todos os peers, por padrão, pertecem ao World Peer Group, que é o primeiro grupo da
rede JXTA, e pai de todos os outros grupos. O World Peer Group oferece alguns serviços
básicos, como por exemplo a descoberta de novos peers, e outras funcionalidades simples.
Depois de iniciado os serviços básicos da rede JXTA, nosso peer irá se integrar ao Net
Peer Grupo, um grupo especial que oferece serviços e funcionalidades adicionais ao World
Peer Group, como por exemplo, o monitoramento de serviços, definições de credenciais e
conhecimento de gateways específicos. O principal motivo para a separação do Net Peer
Group do World Peer Group, deve-se ao fato de JXTA não fazer nenhuma imposição aos
requisitos mínimos do peers participantes da rede. Caso os recursos utilizados por um
determinado peer sejam compatíveis com Net Peer Group, este poderá instancia-lo sem
restrições, e caso contrário, poderá apenas usufruir dos serviços básicos oferecidos pelo
World Peer Group.
Após ingressar no Net Peer Group, utilizaremos os métodos getDiscoveryService() e
getPipeService() para obter os serviços de Discovery e Pipe, respectivamente.
10
20
30
40
50
60
70
try{
group=PeerGroupFactory.newNetPeerGroup();
}catch(Exception e){
e.printStackTrace();
}
discovery=group.getDiscoveryService();
pipeSvc=group.getPipeService();
Exemplo 2 – Depois de iniciado o Net Peer Group, os serviços de Pipe e Discovery são recuperados.
63
A interface DiscoveryService especifica diversos métodos para recuperação,
publicação
e
descoberta
de
advertisements
,
implementados
pela
classe
DiscoveryServiceImpl. Publicar advertisements é uma das principais tarefas de qualquer
aplicação na rede JXTA, pois é desta maneira que são feitas as descobertas de peers, pipes e
outros recursos.
Após recuperado os serviços de discovery e pipes, e caso não nenhum erro seja
encontrado, instanciaremos a classe chat.ChatLoginFrame, permitindo ao usuário escolher o
nick a ser utilizado, e dando início a aplicação. O método responsável por realizar o login
deste usuário no chat, é o método public int loginChat(String name).
A primeira ação realizada por este método, é verificar se o login na aplicação de chat
ainda não foi realizado, alertando o usuário de que não será possível entrar na rede novamente
caso o login já tenha sido escolhido. Com o serviço de discovery recuperado corretamente,
registraremos a própria classe chat.ChatApp como ouvinte para os eventos de discovery
recebidos.
10
20
30
40
if(!loggedIn){
this.nick=name;
discovery.addDiscoveryListener(this);
}
Exemplo 3 - Caso o apelido escolhido esteja disponível, registramos a classe atual como listenet dos
eventos recebidos de Discovery recebidos pela aplicação.
Para que a classe possa receber eventos de discovery, é necessário que o método
public void discoveryEvent(DiscoveryEvent ev) seja implementado, fornecendo as ações que
o programa deve realizar ao receber um evento. Nesta aplicação, este método apenas informa
o recebimento de um evento, sem qualquer ação específica que envolva a lógica da aplicação.
64
Em seguida procuramos um advertisement localmente para o nick informado. A
distinção dos advertisements que pertencem a nossa aplicação é feita pela recuperação do
valor contido no elemento <Name> do xml correspondente ao advertisement de pipes
encontrados. Todo advertisement enviado pela aplicação de chat, conterá o prefixo que foi
definido na constante CHAT_NAME_TAG, além do nick escolhido pelo usuário no início da
aplicação:
10
public static final String CHAT_NAME_TAG="ChatMack";
Exemplo 4 – Constante definindo o elemento a ser anexado nos advertisements publicados pela aplcação
na rede JXTA, permitindo a identificação futura pelos outros clientes do chat.
Caso já exista um advertisement armazenado localmente no cache da aplicação,
informaremos que já existe um outro usuário com este mesmo nick participando do chat, e
solicitamos a escolha de outro nick para o usuário atual.
Não existindo um outro usuário com o mesmo nick na rede JXTA para a aplicação de
chat, criamos um novo advertisement para o pipe de entrada, que será utilizado para o
recebimento de mensagens, e logo em seguida, realizamos a publicação deste advertisement
para os outros peers, alertando a presença deste novo usuário:
10
20
30
40
50
60
70
80
90
100
110
120
130
140
try{
//criando um adv de pipe para este user...
adv = (PipeAdvertisement) _
AdvertisementFactory.newAdvertisement _
(PipeAdvertisement.getAdvertisementType());
adv.setPipeID(IDFactory.newPipeID _
(group.getPeerGroupID()));
adv.setName(CHAT_NAME_TAG+":"+name);
adv.setType(PipeService.PropagateType);
}catch(Exception e){
e.printStackTrace();
return -1;
}
65
Exemplo 5 - Criação do advertisement para o Pipe que receberá as mensagens do chat.
10
20
30
40
50
60
70
80
90
try{
discovery.publish(adv,DiscoveryService.ADV, _
ADV_LIFETIME,ADV_LIFETIME);
discovery.remotePublish(adv,DiscoveryService.ADV, _
ADV_LIFETIME);
}catch(Exception e){
e.printStackTrace();
return -1;
}
Exemplo 6 - Publicação do advertisement de Pipe na rede JXTA.
O método private void createInputPipe() é responsável pela criação do pipe de entrada.
A partir deste momento qualquer mensagem enviada para este pipe será recebida pelo método
public void pipeMsgEvent(PipeMsgEvent pipeMsgEvent):
10
20
30
40
50
60
70
try{
pipeIn=pipeSvc.createInputPipe(userAdv,this);
}catch(Exception e){
System.out.println("Erro ao criar _
inputPipe:"+e.getMessage());
return;
}
Exemplo 7 - Criação do Pipe de entrada que recebe as mensagens enviadas no chat.
O parâmetro “this” informado no método createInputPipe, especifica qual classe deve
implementar o método de recebimento de eventos de pipe. Nesta aplicação a própria classe
chat.ChatApp fornece a implementação, como veremos a seguir:
10
20
30
40
public void discoveryEvent(DiscoveryEvent ev){
DiscoveryResponseMsg res=ev.getResponse();
String name="Unknown";
PeerAdvertisement peerAdv=res.getPeerAdvertisement();
Exemplo 8 - Implementação do método responsável por tratar os eventos de Discovery recebidos.
Depois de recuperado o evento recebido, extraímos o remetente e a mensagem enviada
por ele, definidas pelos valores contidos nas constantes private static final String
SENDER_NAME="ChatSenderName"
e
private
static
final
String
66
MESSAGE_TAG="ChatSenderMessage", respectivamente. Com a mensagem e o remetente
recuperados,
executamos
o
método
chatFrame.printMessage(msg,from)
da
classe
chat.ChatFrame, responsável pela exibição formatada da mensagem na tela.
O método public void sendMessageToAll(String texto) é responsável pelo envio de
mensagens para o chat. A cada mensagem enviada por este usuário, precisamos recuperar
todos os advertisements de pipes armazenados no cache local de nossa aplicação, criar um
pipe de saída para cada pipe encontrado, e enviar a mensagem, repetidamente para cada peer.
O método private Collection getAllPipeLocalAdvertisements() é o responsável por recuperar
os advertisements armazenados localmente pela aplicação:
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
private Collection getAllPipeLocalAdvertisements(){
Collection pipes=new ArrayList();
try{
Enumeration enum=discovery.getLocalAdvertisements( _
DiscoveryService.ADV,
"Name","*"+CHAT_NAME_TAG+":*");
if(enum!=null){
while(enum.hasMoreElements()){
try{
PipeAdvertisement _
adv=(PipeAdvertisement)_
enum.nextElement();
pipes.add(adv);
}catch(Exception e){
continue;
}
}
}
}catch(Exception e){
e.printStackTrace();
}
return pipes;
}
Exemplo 9 - Recuperação dos Advertisements armazenados em cache pela aplicação.
Ao criar um pipe de saída para cada advertisement recuperado, estabelecemos um
timeout de 100 ms para realizar a conexão. Se o peer responsável pela publicação do pipe não
67
puder ser contato, ignoramos este advertisement e repetimos o mesmo processo para os
restantes encontrados.
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
public void sendMessageToAll(String texto){
Collection pipes=getAllPipeLocalAdvertisements();
if(pipes!=null){
Iterator it=pipes.iterator();
while(it.hasNext()){
PipeAdvertisement adv=(PipeAdvertisement) _
it.next();
OutputPipe pipeOut=null;
try{
pipeOut=pipeSvc.createOutputPipe(adv,100);
}catch(Exception e){
System.out.println("\nErro ao Criar _
pipeOut para "+adv.getName());
}
if(pipeOut!=null){
Message msg=null;
String userInput=null;
InputStream inputStream=null;
try{
msg=pipeSvc.createMessage();
//inputStream = new _
ByteArrayInputStream()
StringMessageElement sme=new _
StringMessageElement(SENDER_NAME,_
nick,null);
StringMessageElement sme2=new _
StringMessageElement(MESSAGE_TAG,_
texto,null);
msg.replaceMessageElement(sme);
msg.replaceMessageElement(sme2);
pipeOut.send(msg);
}catch(Exception e){
System.out.println("Erro ao enviar_
conteudo para pipeOut:" _
+e.getMessage());
}
}
}
}
}
Exemplo 10 - Envio da mensagem para cada pipe recuperado através dos advertisements armazenados no
cache da aplicação.
68
6. CONCLUSÃO
A necessidade de um tipo de computação descentralizada, mais colaborativa,
transiente e adaptativa aumenta à medida que surgem novos dispositivos e plataformas. Com
a popularização dos dispositivos móveis, como os Palm Tops, Hand Helds e celulares de
última geração, torna-se clara a necessidade de comunicação entre dispositivos pertencentes a
redes diferentes e plataformas distintas.
A iniciativa do projeto JXTA, com o objetivo de especificar protocolos independentes
de plataforma, dispositivo ou linguagem de programação, torna-se fundamental para a
construção de novas aplicações P2P, além da possibilidade de integrar, sem grandes
dificuldades, as novas aplicações que serão construídas seguindo as futuras especificações a
serem definidas em JXTA.
Outro fator fundamental para o sucesso futuro do projeto, é o fato dele não ser
proprietário, apesar de ter sido iniciado e ainda incentivado pela Sun Microsystem.
Atualmente o projeto JXTA é mantido sob uma variação da Apache Software License, o que
garante a continuidade do projeto independente de qualquer empresa, além da contribuição
constante da comunidade open-source, e a transparência de como o desenvolvimento da
tecnologia é conduzido.
Muitas dificuldades e problemas ainda precisam ser resolvidos. O consumo excessivo
de banda para realização de buscas em redes P2P, utilizando técnicas como flooding, precisa
69
ser melhorado. A falta de implementações em outras linguagens além do java, ainda torna
restrito o uso da tecnologia, fato que deve ser resolvido em breve com novas implementações.
A versão JXTA 2.1.1, sendo a mais recente lançada até o momento, traz diversas
otimizações em relação à primeira versão, como a possibilidade da utilização de sockets,
similares aos disponíveis na versão J2SE, além da criação de pipes bidirecionais, otimizando a
troca de mensagens entre peers. Muitas outras otimizações relativas aos recursos de rede
utilizados foram adicionadas, e diversas API´s foram alteradas para simplificar o
desenvolvimento e aperfeiçoar as já existentes. A cada versão disponibilizada, torna-se
fundamental a participação da comunidade envolvida no projeto, que através de listas de
discussões, identifica os pontos falhos e analisa novas necessidades para que em um futuro
breve, esta tecnologia possa ser utilizada em larga escala pela indústria com sucesso.
Diversos sub-projetos estão sendo desenvolvidos paralelamente ao projeto JXTA,
disponibilizando soluções e alternativas importantes para a indústria de tecnologia. Entre
esses sub-projetos, podemos destacar o vop2p (Voice Over Peer to Peer), disponível em
http://vop2p.jxta.org/servlets/ProjectHome, que tem como objetivo a possibilidade de criação
de uma rede telefônica descentralizada para comunicação entre peers. Além do vop2p, outros
projetos merecem destaque, como o gamePlataform (Plataforma para jogos on-line
possibilitando
vários
participantes),
disponível
em
http://gameplatform.jxta.org/servlets/ProjectHome, e o p2pConference, disponível em
http://p2pconference.jxta.org/servlets/ProjectHome, que permite a criação de conferências
virtuais sobre a plataforma JXTA. Outros sub-projetos estão sendo adicionados mensalmente
ao projeto JXTA, e o amadurecimento e a estabilidade das próximas versões da plataforma,
devem favorecer o surgimento de aplicações realmente inovadoras para o setor de tecnologia.
70
Apesar das dificuldades existentes, o desenvolvimento e amadurecimento para
construção de redes P2P vêm sendo notado a cada ano, bastando observar o sucesso na
utilização de aplicativos compartilhadores de arquivos e de troca de mensagens instantâneas.
A adoção de aplicações P2P por empresas privadas deve popularizar a tecnologia, e
conseqüentemente disponibilizar e capacitar mão de obra para o desenvolvimento de novas
aplicações P2P em JXTA.
Mesmo com poucos anos de desenvolvimento, a implementação para linguagem java
da plataforma JXTA ,mostra-se bastante avançada, permitindo a construção de aplicações P2P
sem grandes dificuldades e com resultados satisfatórios. Porém, a melhora da documentação,
sendo traduzida em outras linguagens além do inglês, além da publicação de novos livros e
artigos sobre o assunto, será fundamental para a adoção desta tecnologia por diversos
arquitetos de soluções P2P e pelas empresas de tecnologia.
A aplicação de chat desenvolvida neste trabalho, pode servir de ponto de partida para
os interessados nas API´s java para desenvolvimento de aplicação P2P utilizando a plataforma
JXTA, além de permitir o entendimento de vários sub-projetos e códigos disponibilizados no
site oficial do projeto.
71
REFERÊNCIAS BIBLIOGRÁFICAS
[1] TRUELOVE, Kelly. 2001. Gnutella and the Transient Web. Online, disponível em
http://www.openP2P.com/lpt/a/705. Publicado em março de 2001; último acesso em outubro
de 2003.
[2] ANDY, Oram. 2000. Gnutella and Freenet represent true technological innovation. Online,
disponível em http://www.oreillynet.com/lpt/a/208. Publicado em maio de 2000; último
acesso em outubro de 2003.
[3] ORAM, Andy. 2001. O poder transformador das redes P2P. Berkeley Brasil, 2001.
[4] SUN MICROSYSTEMS, INC.. 2001. Project JXTA: An open, Innovative Collaboration.
Online, disponível em http://www.jxta.org/project/www/docs/OpenInnovative.pdf. Publicado
em abril de 2001; último acesso em outubro de 2003.
[5] Web site SETI@home. Online, disponível em http://setiathome.ssl.berkeley.edu/. Último
acesso em outubro de 2003.
[6] PARAMESWARAN, Manoj; SUSARLA, Anjana; WHINSTON , Andrew B.. 2001. P2P
Networking: An information –Sharing Alternative. Online, disponível em
http://cism.bus.utexas.edu/works/articles/PARA.Cxs2final.pdf. Publicado em julho de 2001;
último acesso em outubro de 2003.
[7] GONG, Li. 2001. JXTA: A network programming environment. Online, disponível em
http://www.jxta.org/project/www/docs/JXTAnetworkProgEnv.pdf. Publicado em junho de
2001; último acesso em outubro de 2003.
[8] GONG, Li. 2002. Project JXTA: A Technology Overview. Online, disponível em
http://www.jxta.org/project/www/docs/jxtaview_01nov02.pdf. Publicado em Outubro de
2002; último acesso em outubro de 2003.
72
[9] TRAVERSAT, Bernard; ABDELAZIZ, Mohamed; DUIGOU, Mike; HUGLY, JeanChristophe; POUYOUL, Eric; YEAGER, Bill. 2002. Project JXTA Virtual Network. Online,
disponível em http://www.jxta.org/docs/JXTAprotocols.pdf. Publicado em fevereiro de 2002;
último acesso em outubro de 2003.
[10] TRAVERSAT, Bernard; ARORA, Ahkil; ABDELAZIZ, Mohamed; DUIGOU, Mike;
HAYWOOD, Carl; HUGLY, Jean-Christophe; POUYOUL, Eric; YEAGER, Bill. 2003.
Project JXTA 2.0 Super-Peer Virtual Network. Online, disponível em
http://www.jxta.org/project/www/docs/JXTA2.0protocols1.pdf. Publicado em maio de 2003;
último acesso em outubro de 2003.
[11] KRISHNAN, Navaneeth. 2003. Master the Jxta shell, Part 1. Online, disponível em
http://www.javaworld.com/javaworld/jw-01-2002/jw-0111-jxtashell_p.html. Publicado em
janeiro de 2003; último acesso em outubro de 2003.
[12] SUN MICROSYSTEMS, INC.. 2001 Project JXTA: Technical Shell Overview. Online,
disponível em http://www.jxta.org/project/www/docs/GettingStarted.pdf. Publicado em abril
de 2001; último acesso em outubro de 2003.
[13] OAKS, Scott; TRAVERSAT, Bernard; GONG, Li. Getting Started with JXTA, Part 1.
Online, disponível em http://www.onjava.com/lpt/a/2619. Último acesso em outubro de 2003.
[14] OAKS, Scott; TRAVERSAT, Bernard; GONG, Li. Getting Started with JXTA, Part 2.
Online, disponível em http://www.onjava.com/lpt/a/2620. Último acesso em outubro de 2003.
[15] OAKS, Scott; TRAVERSAT, Bernard; GONG, Li. Getting Started with JXTA, Part 3.
Online, disponível em http://www.onjava.com/lpt/a/2621. Último acesso em outubro de 2003.
[16] OAKS, Scott; TRAVERSAT, Bernard; GONG, Li. Getting Started with JXTA, Part 4.
Online, disponível em http://www.onjava.com/lpt/a/2726. Último acesso em outubro de 2003.
[17] OAKS, Scott; TRAVERSAT, Bernard; GONG, Li. Getting Started with JXTA, Part 5.
Online, disponível em http://www.onjava.com/lpt/a/2725. Último acesso em outubro de 2003.
73
[18] KURNIAWAN, Budi. A JXTA Chat. Online, disponível em
http://www.fawcette.com/javapro/2001_12/magazine/features/bkurniawan/. Último acesso em
outubro de 2003.
[19] MINAR, Nelson. 2001. JXTA Chat, Sans Server. Online, disponível em
http://www.openP2P.com/lpt/a/912. Publicado em junho de 2001; último acesso em outubro
de 2003.
[20] BAEHNI, Sebastien. Wire chat. Online, disponível em
http://lpdwww.epfl.ch/sbaehni/work/jxta/wireChat/pages/wireChat.html. Último acesso em
outubro de 2003.
[21] SUN MICROSYSTEMS, INC.. 2003. Project JXTA Technology:Creating Connected
Communities. Online, disponível em http://jxta-wire.jxta.org/project/www/docs/JXTA-ExecBrief-032803.pdf. Publicado em março de 2003; último acesso em outubro de 2003.
[22] SUN MICROSYSTEMS, INC.. Project JXTA. Online, disponível em
http://wwws.sun.com/software/jxta/. Último acesso em outubro de 2003.
[23] CLAßEN, Michael. 2001. Project JXTA: An Open, Peer-to-Peer Collaboration Platform
using Java and XML. Online, disponível em
http://www.webreference.com/xml/column32/index.html. Publicado em maio de 2001; último
acesso em outubro de 2003.
[24] SUN MICROSYSTEMS, INC.. Project JXTA: Scenarios. Online, disponível em
http://wwws.sun.com/software/jxta/features/scenarios.html. Último acesso em outubro de
1003.
[25] KRISHNAN, Navaneeth. 2001. The Jxta solution to P2P. Online, disponível em
http://www.javaworld.com/javaworld/jw-10-2001/jw-1019-jxta_p.html. Publicado em
outubro de 2001; último acesso em outubro de 2003.
74
[26] KRIKORIAN, Raffi. 2001. Hello JXTA!. Online, disponível em
http://www.onjava.com/lpt/a/802. Publicado em abril de2001; último acesso em outubro de
2003.
[27] DORNFEST, Rael. 2001. JXTA Takes Its Position. Online, disponível em
http://www.openP2P.com/pub/a/P2P/2001/04/25/jxta_position.html. Publicado em abril de
2001; último acesso em outubro de 2003.
[28] SUN MICROSYSTEMS, INC.. 2002. Five Abstractions. Online, disponível em
http://www.sun.com/2002-0604/feature/five-ab.html. Publicado em junho de 2002; último
acesso em outubro de 2003.
[29] SUN MICROSYSTEMS, INC.. 2002. Six Protocols. Online, disponível em
http://www.sun.com/2002-0604/feature/six.html. Publicado em junho de 2002; último acesso
em outubro de 2003.
[30] HALEPOVIC, Emir; DETERS, Ralph. The Costs of Using JXTA. Online, disponível em
http://bistrica.usask.ca/madmuc/Grads/Emir/pub/P2P03_Halepovic_CostsOfUsingJXTA.pdf.
Último acesso em outubro de 2003.
[31] ROCHA, Rafael R.. 2003. Redes Peer-to-Peer para Compartilhamento de Arquivos. Online,
disponível em http://www.gta.ufrj.br/seminarios/semin2003_1/rafael/principal.htm.
Publicado em junho de 2003; último acesso em outubro de 2003.
[32] SUNDSTED, Todd. 2001. The practice of peer-to-peer computing: Introduction and history.
Online, disponível em http://www-106.ibm.com/developerworks/java/library/j-P2P/.
Publicado em março de 2001; último acesso em outubro de 2003.
[33] SUNDSTED, Todd.. 2001. The practice of peer-to-peer computing: Discovery. Online,
disponível em http://www-106.ibm.com/developerworks/java/library/j-P2Pdisc/. Publicado
em novembro de 2001. último acesso em outubro de 2003.
[34] LI, Sing. 2002. P2P interoperable: Creating JXTA systems. Online, disponível em
75
http://www-106.ibm.com/developerworks/java/library/j-P2Pint3/. Publicado em abril de
2002; último acesso em outubro de 2003.
[35] SUNDSTED, Todd.. 2002. The practice of peer-to-peer computing: IP Multicast-based
discovery. Online, disponível em http://www-106.ibm.com/developerworks/java/library/jP2Pdisc2/. Publicado em janeiro de 2002; último acesso em outubro de 2003.
76
GLOSSÁRIO
Browser
Designação genérica do tipo de programa que nos permite navegar na Internet (Internet
Explorer, Netscape Navigator, etc).
Cache
Refere-se ao local onde os dados são armazenados temporariamente.
Distributed Network
Uma rede na qual o processamento, o armazenamento e outras funções são executados em
unidades (nós) separados, e não concentradas em um único computador.
Firewall
Um sistema de segurança ( hardware e/ou software ) cujo principal objetivo é filtrar os
acessos a uma rede. As empresas utilizam o firewall para proteger as suas redes internas
conectadas à Internet contra a entrada de pessoas não autorizadas. (Hackers). Existem
diversas tecnologias possíveis para a construção de um Firewall.
Gateway
Sistema que permite o intercâmbio de serviços e informações entre redes com tecnologias
iguais ou distintas.
HTTP
Hyper Text Transfer Protocol (Protocolo de transferência de Hipertexto). O HTTP é o
protocolo usado para a transmissão de dados no sistema World-Wide Web.
JXTA
Sigla para a JustaPose, uma tecnologia para construção de aplicativos P2P independente de
plataforma e dispositivos, liderada pela SUN Microsystem.
77
NAT
Sigla para Network Address Translation. Ocorre quando vários endereços IP em uma LAN
(Local área network) privada são convertidos para um endereço público. Esse endereço
público é enviado para a Internet. A NAT acrescenta níveis de segurança porque o endereço
IP de um PC conectado a LAN privada nunca é transmitido para a Internet. O usuário pode ter
vários endereços privados mascarados pelo endereço único fornecido pelo Provedor Internet.
A NAT evita rejeições de serviço (DoS) de redes externas em hosts internos.
P2P
Peer to Peer, comunicação direta entre dois pontos sem a necessidade de um intermediário. Os
peers geralmente possuem capacidades e responsabilidades iguais em uma rede. Uma rede
P2P é formada pelo conjunto de diversos peers participantes.
Proxy
Sevidor que atua como um intermediário entre a estação de trabalho e a Internet ou alguma
outra rede, garantindo um certo nível de segurança por realizar uma comunicação indireta.
Serviços como controle administrativo, limitação de recursos utilizados e cache podem ser
fornecidos, dependendo da implementação utilizada.
TCP/IP
Transmission Control Protocol/Internet Protocol. Conjunto de protocolos da Internet que
definem como se processam as comunicações entre vários computadores PDAs.
78
APÊNDICE A – CÓDIGOS FONTE DA IMPLEMENTAÇÃO
Arquivo ChatApp.java
package chat;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.io.InputStream;
java.text.DateFormat;
java.util.ArrayList;
java.util.Collection;
java.util.Date;
java.util.Enumeration;
java.util.Iterator;
java.util.Locale;
net.jxta.discovery.DiscoveryEvent;
net.jxta.discovery.DiscoveryListener;
net.jxta.discovery.DiscoveryService;
net.jxta.document.AdvertisementFactory;
net.jxta.endpoint.Message;
net.jxta.endpoint.StringMessageElement;
net.jxta.id.IDFactory;
net.jxta.peergroup.PeerGroup;
net.jxta.peergroup.PeerGroupFactory;
net.jxta.pipe.InputPipe;
net.jxta.pipe.OutputPipe;
net.jxta.pipe.PipeMsgEvent;
net.jxta.pipe.PipeMsgListener;
net.jxta.pipe.PipeService;
net.jxta.protocol.DiscoveryResponseMsg;
net.jxta.protocol.PeerAdvertisement;
net.jxta.protocol.PipeAdvertisement;
net.jxta.rendezvous.RendezVousService;
org.apache.log4j.Logger;
/**
* Classe principal para aplicação do chat P2P, implementa as interfaces
PipeMsgListener
* para recebimento de eventos de pipes e DiscoveryListener para eventos de
Discovery
* de novos peers.
*/
public class ChatApp implements PipeMsgListener, DiscoveryListener {
/**
* Nome do elemento que definirá qual advertisement de pipe pertence
a este chat.
*/
public static final String CHAT_NAME_TAG = "ChatMack";
/**
* Tempo de vida do advertisement de pipe na rede. Após isso o chat
parará de funcionar.
*/
private static final long ADV_LIFETIME = 210 * 1000;
/**
79
* Frame responsável por exibir e enviar as mensagens para outros
usuários.
*/
private static ChatFrame chatFrame;
/**
* Frame responsável por recuperar o nick escolhido.
*/
private static ChatLoginFrame chatLoginFrame;
/**
* Log 'chat' definido em classes/log4j.xml.
*/
private static Logger log = Logger.getLogger("chat");
/**
* Nome do elemento que conterá mensagem enviada por um usuário.
*/
private static final String MESSAGE_TAG = "ChatSenderMessage";
/**
* Nome do elemento que conterá o nome do enviador da mensagem
*/
private static final String SENDER_NAME = "ChatSenderName";
/**
* Tempo de espera antes de tentar recuperar após um advertisement
após um publish.
*/
private static final int WAITING_TIME = 5 * 1000;
private DiscoveryService discovery;
private PeerGroup group;
/**
* Indica se o flush de advertisements já foi realizado.
*/
private boolean isFlushed;
/**
* Indica se o usuário atual já esta logado.
*/
private boolean loggedIn;
/**
* Nick escolhido pelo usuário.
*/
private String nick;
private PipeService pipeSvc;
private RendezVousService rdv;
/**
* Irá procurar remotamente novos advertisements.
*/
private Thread thread;
/**
80
* Utilizado para recebimento das mensagens enviadas para este
usuário.
*/
private PipeAdvertisement userAdv;
/**
*Método para exibição formatada de data
*@return String contendo data no formato dd/mm/aa hh:mm
*@see <code>java.text.DateFormat#getDateTimeInstance(int, int,
java.util.Locale)</code>
*/
public static String getShortDate() {
DateFormat df =
DateFormat.getDateTimeInstance(
DateFormat.SHORT,
DateFormat.SHORT,
new Locale("pt", "BR"));
return df.format(new Date(System.currentTimeMillis()));
}
public static void main(String args[]) {
ChatApp chat = new ChatApp();
log.debug("Aplicação iniciada...");
chat.startJxta();
}
/**
* Cria um input pipe e adiciona a própria classe como ouvinte de
eventos recebido
* por este pipe
*/
private void createInputPipe() {
InputPipe pipeIn = null;
try {
pipeIn = pipeSvc.createInputPipe(userAdv, this);
} catch (Exception e) {
log.fatal("Impossível criar pipe de entrada:" +
e.getMessage());
System.exit(-1);
}
log.info("Pipe de entrada criado com sucesso...");
}
/**
* Recebe os eventos de discovery para esta classe. Apenas registra
no log
* os advertisements recebidos pertencente a este chat, e mostra
* quais foram as respostas recebidas e por quem foram enviadas
*
* @param ev Evento de Discovery recebido
*/
public void discoveryEvent(DiscoveryEvent ev) {
DiscoveryResponseMsg res = ev.getResponse();
String name = "Unknown";
PeerAdvertisement peerAdv = res.getPeerAdvertisement();
if (peerAdv != null) {
name = peerAdv.getName();
}
log.debug(
81
res.getResponseCount()
+ " resposta[s] de discovery recebida[s] de "
+ name
+ "...");
PipeAdvertisement adv = null;
Enumeration enum = res.getAdvertisements();
if (enum != null) {
while (enum.hasMoreElements()) {
try {
adv = (PipeAdvertisement) enum.nextElement();
log.debug(
"Pipe para usuário '"
+ adv.getName()
+ "' recuperado no evento de
discovery:\n"
+ adv.toString());
} catch (Exception e) {
}
}
}
}
/**
* Procura por advertisements de pipe de um determinado usuário
localmente
* e remotamente
* @param name Nick de qual usuário que desejamos procurar advs
* @return <code>PipeAdvertisement</code> contendo o advertisement
recuperado
* para este usuário ou null, caso nenhum tenha sido encontrado.
* @see #findUserAdvLocal(String).
* @see #findUserAdvRemote(String).
*/
private PipeAdvertisement findUserAdv(String name) {
PipeAdvertisement adv = findUserAdvLocal(name);
if (adv == null) {
adv = findUserAdvRemote(name);
adv = findUserAdvLocal(name);
}
return adv;
}
/**
* Realiza o flush dos advertisements locais, e recupera
* os advertisements ainda validos que correspondam a esta aplicação
de chat,
* procurando por um usuário específico.
*
* @param name Nick do usuário desejado.
* @return null ou PipeAdvertiment já atribuído a este usuário
anteriormente.
*/
private PipeAdvertisement findUserAdvLocal(String name) {
Enumeration enum = null;
try {
if(isFlushed){
discovery.flushAdvertisements(null,
DiscoveryService.ADV);
82
log.info(" flush de advertisements executados com
sucesso...");
}
enum =
discovery.getLocalAdvertisements(
DiscoveryService.ADV,
"Name",
CHAT_NAME_TAG + ":" + nick);
if (enum != null) {
PipeAdvertisement adv = null;
while (enum.hasMoreElements()) {
try {
adv = (PipeAdvertisement)
enum.nextElement();
if ((CHAT_NAME_TAG + ":" + name)
.equals(adv.getName())) {
return adv;
}
} catch (Exception e) {
}
}
}
} catch (Exception e) {
log.error(
"Erro ao recuperar advertisements de cache:" +
e.getMessage());
}
return null;
}
/**
* Procura remotamente os advertisements de pipe desta
aplicação
* e que correspondam a um determinado usuário informado.
*
* @param name Nick do usuário desejado
* @return null ou <code>PipeAdvertiment</code> deste usuário
válido na rede JXTA
*/
private PipeAdvertisement findUserAdvRemote(String name) {
PipeAdvertisement adv = null;
try {
//ache todos os advertisiments locais de pipes publicados
por esta aplicação....
discovery.getRemoteAdvertisements(
null,
DiscoveryService.ADV,
"Name",
"*" + CHAT_NAME_TAG + ":*",
2);
try {
Thread.sleep(WAITING_TIME);
} catch (Exception e) {
}
} catch (Exception e) {
log.error(
"Erro ao recuperar advertisements remotos:" +
e.getMessage());
83
}
return null;
}
/**
* Recupera todos os advertisements locais desta aplicação,
* verificando qual corresponde a PipeAdvertisement.
*
* @return <code>Collection</code> contendo todos os
PipeAdvertisement encontrados.
*/
private Collection getAllPipeLocalAdvertisements() {
Collection pipes = new ArrayList();
try {
Enumeration enum =
discovery.getLocalAdvertisements(
DiscoveryService.ADV,
"Name",
"*" + CHAT_NAME_TAG + ":*");
if (enum != null) {
while (enum.hasMoreElements()) {
try {
PipeAdvertisement adv =
(PipeAdvertisement)
enum.nextElement();
pipes.add(adv);
} catch (Exception e) {
continue;
}
}
}
} catch (Exception e) {
log.error(
"Erro ao recuperar cache de advertisements:" +
e.getMessage());
}
return pipes;
}
public String getNick() {
return nick;
}
/**
* Efetua o login na aplicação de chat, criando um PipeAdvertisement
* para este usuário, e publicando este pipe localmente e remotamente
* na rede JXTA. Após realizada a publicação do advertisement,o frame
que exibe e permite
* o envio de mensagens é exibido, uma mensagem para todos é enviada
* alertando a presença de um novo usuário, e uma thread é iniciada
para descoberta
* de novos advertisements na rede JXTA. Caso haja algum problema
antes de terminar a rotina,
* a aplicação é encerrada com código de erro -1.
*
* @param name Nick escolhido pelo usuário na tela de login
* @return <code>int</code> , -1 caso o usuário já tenha realizado
* o login anteriormente, ou 1 caso tudo tenha sido realizado com
sucesso.
84
*/
public int loginChat(String name) {
if (!loggedIn) {
this.nick = name;
discovery.addDiscoveryListener(this);
PipeAdvertisement adv = findUserAdv(name);
if (adv != null) {
log.fatal(
"Erro, Advertisiment já existente para este
usuário, saindo da aplicação...");
System.exit(-1);
}
try {
//criando um adv de pipe para este user...
adv =
(PipeAdvertisement)
AdvertisementFactory.newAdvertisement(
PipeAdvertisement.getAdvertisementType());
adv.setPipeID(IDFactory.newPipeID(group.getPeerGroupID()));
adv.setName(CHAT_NAME_TAG + ":" + name);
adv.setType(PipeService.PropagateType);
} catch (Exception e) {
log.fatal(
"Impossível criar advertisement de pipe:" +
e.getMessage());
System.exit(-1);
}
try {
discovery.publish(
adv,
DiscoveryService.ADV,
ADV_LIFETIME,
ADV_LIFETIME);
discovery.remotePublish(
adv,
DiscoveryService.ADV,
ADV_LIFETIME);
} catch (Exception e) {
log.fatal(
"Impossível publicar advertisement de pipe:"
+ e.getMessage());
System.exit(-1);
}
adv = findUserAdvLocal(name);
if (adv == null) {
log.fatal(
"Impossível recuperar advertisement de pipe
para este usuário...");
System.exit(-1);
}
userAdv = adv;
loggedIn = true;
createInputPipe();
chatFrame.setTitle(getNick() + " - JXTA Chat P2P ");
chatFrame.show();
sendMessageToAll(" Entrei no chat....");
85
//thread que vai recuperar novos pipes de tempos em
tempos...
log.info("Criando thread para Discovery de pipes...");
DiscoveryPipes discoveryPipes = new
DiscoveryPipes(discovery);
} else {
log.fatal("Atenção , você já esta logado no chat...");
return -1;
}
return 1;
}
public void pipeMsgEvent(PipeMsgEvent pipeMsgEvent) {
try {
Message message = pipeMsgEvent.getMessage();
String from =
message.getMessageElement(SENDER_NAME).toString();
String msg =
message.getMessageElement(MESSAGE_TAG).toString();
chatFrame.printMessage(msg, from);
} catch (Exception e) {
log.error("Erro ao receber evento de pipe:" +
e.getMessage());
}
}
public void sendMessageToAll(String texto) {
Collection pipes = getAllPipeLocalAdvertisements();
if (pipes != null) {
Iterator it = pipes.iterator();
while (it.hasNext()) {
PipeAdvertisement adv = (PipeAdvertisement)
it.next();
OutputPipe pipeOut = null;
try {
pipeOut = pipeSvc.createOutputPipe(adv, 100);
} catch (Exception e) {
log.error(
"Erro ao criar OutputPipe para '"
+ adv.getName()
+ "':"
+ e.getMessage());
}
if (pipeOut != null) {
Message msg = null;
String userInput = null;
InputStream inputStream = null;
try {
msg = pipeSvc.createMessage();
//inputStream=new ByteArrayInputStream()
StringMessageElement sme =
new
StringMessageElement(SENDER_NAME, nick, null);
StringMessageElement sme2 =
new
StringMessageElement(MESSAGE_TAG, texto, null);
msg.replaceMessageElement(sme);
msg.replaceMessageElement(sme2);
pipeOut.send(msg);
} catch (Exception e) {
log.error(
86
"Erro ao enviar mensagem para '"
+ adv.getName()
+ "':"
+ e.getMessage());
}
}
}
}
}
public void startJxta() {
try {
group = PeerGroupFactory.newNetPeerGroup();
log.info("NetPeerGroup iniciado com sucesso...");
} catch (Exception e) {
log.fatal("Erro ao iniciar netPeerGroup:" +
e.getMessage());
System.exit(-1);
}
discovery = group.getDiscoveryService();
rdv = group.getRendezVousService();
log.info("Rendezvous service recuperado...");
while (rdv.isConnectedToRendezVous()) {
try {
log.info("Aguardando conexão com Rendezvous...");
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
log.info(
"Conexão com Rendezvous estabelecida, recuperando serviço
de pipe...");
pipeSvc = group.getPipeService();
chatLoginFrame = new ChatLoginFrame(this);
chatFrame = new ChatFrame(this);
}
}
Arquivo DiscoveryPipes.java
package chat;
import net.jxta.discovery.DiscoveryService;
import org.apache.log4j.Logger;
/**
* Esta classe implementa a interface Runnable, e inicia uma
* thread que procura por novos advertisements na rede a cada 60 segundos.
*/
public class DiscoveryPipes implements Runnable {
private DiscoveryService discoverySvc;
/**
* Log 'chat' definido em classes/log4j.xml.
87
*/
private static Logger log = Logger.getLogger("chat");
/**
* Construtor da classe que recebe o serviço de discovery
(DiscoveryService)
* da classe chat.ChatApp, e inicia uma nova thread para a procura de
Advertisements.
* @see chat.ChatApp
*/
public DiscoveryPipes(DiscoveryService discoverySvc) {
this.discoverySvc = discoverySvc;
Thread t = new Thread(this);
t.start();
log.info("Thread para Discovery de pipes criada e
iniciada....");
}
public void run() {
while (true) {
try {
log.info("Tentando descobrir novos pipes
remotamente...");
discoverySvc.getRemoteAdvertisements(
null,
DiscoveryService.ADV,
null,
null,
100);
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
}
}
}
}
Arquivo ChatLoginFrame.java
package chat;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.Color;
java.awt.MediaTracker;
java.awt.Rectangle;
java.awt.event.ActionEvent;
java.awt.event.KeyEvent;
java.awt.event.KeyListener;
javax.swing.BorderFactory;
javax.swing.ImageIcon;
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JPanel;
javax.swing.JTextField;
88
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import org.apache.log4j.Logger;
public class ChatLoginFrame extends JFrame implements KeyListener {
private static Logger log = Logger.getLogger("chat");
JTextField jtLogin = new JTextField();
JButton jbLogin = new JButton();
JLabel jLabelNick = new JLabel();
JLabel jLabelLogoMack = new JLabel();
TitledBorder titledBorder1;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
Border border1;
JLabel jLabel3 = new JLabel();
JLabel jLabel4 = new JLabel();
JPanel jPanel1 = new JPanel();
JLabel jLabel5 = new JLabel();
private ChatApp chat;
public ChatLoginFrame() {
}
public ChatLoginFrame(ChatApp app) {
chat = app;
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
this.setTitle("Implementação JXTA chat P2P");
border1 = BorderFactory.createLineBorder(Color.white, 1);
jtLogin.setBounds(new Rectangle(5, 184, 171, 21));
this.getContentPane().setLayout(null);
jbLogin.setBounds(new Rectangle(244, 182, 95, 23));
jbLogin.setText("Entrar");
this.setResizable(false);
jLabelNick.setText("Digite abaixo o seu nick:");
jLabelNick.setBounds(new Rectangle(6, 163, 141, 15));
jLabel1.setFont(new java.awt.Font("SansSerif", 1, 12));
jLabel1.setText("Implementação JXTA CHAT");
jLabel1.setBounds(new Rectangle(8, 0, 175, 23));
jLabel2.setText("Antonio Augusto Mariano Da Silva");
jLabel2.setBounds(new Rectangle(5, 12, 197, 17));
jLabel3.setText("Ricardo Augusto Miguel");
jLabel3.setBounds(new Rectangle(6, 36, 205, 20));
jLabel4.setText("Ricardo Ribeiro Tavares");
jLabel4.setBounds(new Rectangle(7, 65, 155, 17));
jPanel1.setBorder(BorderFactory.createEtchedBorder());
jPanel1.setLayout(null);
jPanel1.setBounds(new Rectangle(7, 52, 209, 99));
jLabel5.setFont(new java.awt.Font("SansSerif", 1, 12));
jLabel5.setForeground(Color.red);
jLabel5.setText("Orientador: Prof. Rogério Oliveira");
89
jLabel5.setBounds(new Rectangle(7, 25, 201, 20));
jPanel1.add(jLabel4, null);
jPanel1.add(jLabel3, null);
jPanel1.add(jLabel2, null);
jtLogin.addKeyListener(this);
this.getContentPane().add(jtLogin, null);
this.getContentPane().add(jLabelNick, null);
this.getContentPane().add(jPanel1, null);
this.getContentPane().add(jbLogin, null);
this.getContentPane().add(jLabel5, null);
this.getContentPane().add(jLabel1, null);
this.getContentPane().add(jLabelLogoMack, null);
try {
MediaTracker tracker = new MediaTracker(this);
ImageIcon img = new
ImageIcon(getClass().getResource("logo.gif"));
tracker.addImage(img.getImage(), 0);
tracker.waitForAll();
jLabelLogoMack.setIcon(img);
jLabelLogoMack.setBounds(
new Rectangle(
230,
10,
img.getIconWidth() + 8,
img.getIconHeight() + 8));
} catch (Exception e) {
log.warn("Erro ao carregar imagens:" + e.getMessage());
}
this.setSize(380, 250);
this.setDefaultCloseOperation(3);
jbLogin.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
doLogin();
}
});
show();
}
private void hideFrame() {
this.hide();
}
private void doLogin() {
String nick = jtLogin.getText();
hideFrame();
int resultado = chat.loginChat(nick);
if (resultado < 0) {
JOptionPane.showMessageDialog(
null,
"Atenção, já existe um usuário com este nick no
chat, escolha outro!");
log.fatal("Atenção, já existe um usuário com este nick no
chat, escolha outro!");
System.exit(0);
}
jtLogin.setText("");
}
public void keyPressed(KeyEvent arg0) {
90
if (arg0.getKeyCode() == 10) {
doLogin();
}
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
}
Arquivo ChatFrame.java
package chat;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.MediaTracker;
java.awt.Rectangle;
java.awt.event.ActionEvent;
java.awt.event.KeyEvent;
java.awt.event.KeyListener;
java.util.Date;
javax.swing.ImageIcon;
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JScrollPane;
javax.swing.JTextArea;
javax.swing.JTextField;
org.apache.log4j.Logger;
public class ChatFrame extends JFrame implements KeyListener {
private static Logger log = Logger.getLogger("chat");
private ChatApp chat;
JButton jbEnviar = new JButton();
JLabel jLabelLogoJxta = new JLabel();
JLabel jLabelLogoMack = new JLabel();
JScrollPane jScrollPane1 = new JScrollPane();
JTextField jtMsg = new JTextField();
JTextArea jtMsgAll = new JTextArea();
public ChatFrame(ChatApp chatApp) {
try {
jbInit();
this.chat = chatApp;
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
jtMsg.setBounds(new Rectangle(13, 272, 395, 19));
this.setDefaultCloseOperation(3);
this.getContentPane().setLayout(null);
jbEnviar.setBounds(new Rectangle(439, 272, 77, 21));
jbEnviar.setText("Enviar");
91
//jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SC
ROLLBAR_ALWAYS);
jScrollPane1.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setAutoscrolls(true);
jScrollPane1.setBounds(new Rectangle(13, 8, 402, 251));
jtMsgAll.setWrapStyleWord(true);
jtMsgAll.setBounds(new Rectangle(13, 8, 350, 200));
jtMsgAll.setEditable(false);
jScrollPane1.getViewport().add(jtMsgAll, null);
try {
MediaTracker tracker = new MediaTracker(this);
ImageIcon img = new
ImageIcon(getClass().getResource("logo.gif"));
ImageIcon img2 =
new
ImageIcon(getClass().getResource("logo_jxta.gif"));
tracker.addImage(img.getImage(), 0);
tracker.addImage(img2.getImage(), 0);
tracker.waitForAll();
jLabelLogoMack.setIcon(img);
jLabelLogoMack.setBounds(
new Rectangle(
430,
10,
img.getIconWidth() + 8,
img.getIconHeight() + 8));
jLabelLogoJxta.setIcon(img2);
jLabelLogoJxta.setBounds(
new Rectangle(
430,
120,
img2.getIconWidth() + 8,
img2.getIconHeight() + 8));
} catch (Exception e) {
log.warn("Erro ao carregar imagens:" + e.getMessage());
}
jbEnviar.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e) {
sendMessage(jtMsg.getText());
jtMsg.setText("");
}
});
this.getContentPane().add(jScrollPane1, null);
this.getContentPane().add(jbEnviar, null);
this.getContentPane().add(jtMsg, null);
this.getContentPane().add(jLabelLogoJxta, null);
this.getContentPane().add(jLabelLogoMack, null);
setSize(580, 360);
setResizable(false);
jtMsg.requestFocusInWindow();
jbEnviar.setFocusPainted(true);
jtMsg.addKeyListener(this);
}
public void keyPressed(KeyEvent arg0) {
92
//user apertou enter
if (arg0.getKeyCode() == 10) {
if ("".equals(jtMsg.getText())) {
System.out.println("Mensagem inválida, digite
algo...");
JOptionPane.showMessageDialog(null, "Mensagem
inválida!");
} else {
sendMessage(jtMsg.getText());
jtMsg.setText("");
}
}
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
public void printMessage(String msg) {
jtMsgAll.append("\n" + new Date() + " - " + msg);
}
public void printMessage(String msg, String from) {
String msgFormatada =
ChatApp.getShortDate() + " - " + from + " fala para
todos:" + msg;
jtMsgAll.append("\n" + msgFormatada);
}
public void sendMessage(String mensagem) {
chat.sendMessageToAll(mensagem);
}
}
Arquivo log4j.xml
log4j.rootLogger=WARN,root
log4j.appender.root=org.apache.log4j.ConsoleAppender
log4j.appender.root.layout=org.apache.log4j.PatternLayout
log4j.appender.root.layout.ConversionPattern=%d - %-4r- %3x - [%t] %-5p
(%F:%L) - %m%n
log4j.logger.chat=WARN,a
#log4j.additivity.login=false
log4j.appender.a=org.apache.log4j.RollingFileAppender
log4j.appender.a.File=chat.log
log4j.appender.a.layout=org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern=%d - %-4r- %3x - [%t] %-5p
(%F:%L) - %m%n
93
Antonio Augusto Mariano da Silva
Ricardo Augusto Miguel
Ricardo Ribeiro Tavares
Desenvolvendo aplicações peer-topeer em JAVA com JXTA
Trabalho apresentado à disciplina de
Trabalho de Graduação Interdisciplinar II,
como parte das exigências para a obtenção
do título de Bacharel em Sistemas de Informação
pela Faculdade de Computação e Informática
da Universidade Presbiteriana Mackenzie
Orientador: Rogério de Oliveira
São Paulo
Outubro de 2003
RESUMO
Nos dias atuais, para o desenvolvimento e melhor obtenção de recursos da
Internet, necessitaremos de uma computação distribuída com compartilhamento de
recursos, conteúdo, e estrutura de rede independente, redundante e segura em tempo
real. Neste estudo estaremos apresentando os principais modelos e implementações
atuais de aplicações P2P e as necessidades existentes. Os conceitos envolvidos em uma
construção serão apresentados detalhadamente, e posteriormente aplicados em um
projeto open source Java JXTA, que permitirá um novo tipo de computação distribuída
tornando muito mais fácil as tarefas que as pessoas executam na Web atualmente:
encontrar, obter, utilizar. Codificaremos em JAVA algumas aplicações JXTA simples
que exemplificam o potencial dessa tecnologia.
ABSTRACT
Nowadays, for a development and to get Internet resources, need a the
distributed computing and sharing of resources over the internet need a distributed
computation with resource sharing, content, and independent, redundant and a security
network infrastructure in real time. In this study we are showing the core models and
implementations for peer-to-peer applications and the real necessity of use it. The
concepts involved in construction of peer-to-peer applications are showing deeply, and
after that, we are introducing the main concepts of JXTA, that it will allow a new type
of distributed computation that it becomes much more easy the tasks that the people run
in the Web: search, get, use.To exemplify the power of this technology we are coding
some simple examples like a chat in JAVA with JXTA framework. After read this study
you’ll be able to understand the main concepts of peer-to-peer, and the challeng
involved in it, in addition to develop simple applications using JAVA with JXTA
framework.

Documentos relacionados

Implementação de um Algoritmo para Busca em Redes Peer-to-Peer

Implementação de um Algoritmo para Busca em Redes Peer-to-Peer Sistemas altamente estruturados são também caracterizados por serem menos flexíveis em um ambiente com população de usuários muito transitória, pois há um custo alto para manter a estrutura necess...

Leia mais