Neste artigo iremos atender à solicitação do leitor Wesley Oliveira Gomes, que nos pediu para fazer um Chat em Flex e PHP. Sempre quando pensamos em chats web lembramos daquela tela piscando a cada cinco segundos, algo realmente irritante.
No Flex, é possível manter a comunicação entre o Flex (cliente) e o PHP(servidor) de duas formas distintas. A mais simples, e mais usada, é a comunicação em que somente o Flex faz requisições ao PHP. A mais complexa, também chamada de RTMP (Real Time Messaging Protocol) permite que tanto o Flex se comunique com o PHP quanto o PHP se comunique com o Flex.
Resumindo, nós vamos criar um chat onde o Flex irá, de tempos em tempos, fazer uma requisição ao PHP. Isso é muito semelhante às telas piscantes dos chats web. Mas no Flex não é preciso realizar um POST na página (piscar). Nem é preciso colocar um "loading", ou alterar o ícone do mouse para "carregando". A comunicação entre o Flex e o PHP não será percebida pelo usuário.
O nosso chat será bem simples, não terá salas nem comandos do tipo "/ignore". O usuário, ao acessar a página, irá preencher o seu nome e automaticamente entrar no chat. Haverá um campo para digitar uma mensagem, outro para ver a lista de usuários cadastrados e outro para ver a lista de mensagens, conforme a figura a seguir.
Neste primeiro artigo iremos criar todo o código necessário para que o Flex funcione. Iremos criar, além dos arquivos necessários, um arquivo especial chamado Connection, que será responsável em prover a comunicação com o PHP, além do arquivo ChatManager, que provê as funcionalidades do Chat. A idéia é isolar tudo que se relaciona com o PHP em um único arquivo, para que possamos deixar o chat o mais simples possível. No lado do PHP, iremos utilizar Zend Framework.
Além deste arquivo de comunicação, iremos criar classes que possuem alguma funcionalidade dentro do chat. Estas classes são responsáveis pelos usuários na sala, pelas mensagens trocadas, pelos eventos gerados entre ações, etc.
Comece o seu projeto Flex de acordo com a figura abaixo.
Como podemos ver, criamos o projeto "Chat" na pasta "c:\wamp\www", indicando que estamos usando o WAMP Server. Este detalhe é importante na 2ª parte do artigo.
Após criar o projeto, na tela principal, vamos adicionar o básico em termos de componentes, conforme a figura a seguir.
Isso produz o seguinte resultado:
O código inicial é:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #FFFFFF]">
<mx:Label y="10" text="Chat Flex" left="10"/>
<mx:TextInput y="8" text="Usuário + Enter" left="76"/>
<mx:Canvas left="1" right="9" top="1" bottom="9">
<mx:List id="listMensagens" left="10" right="141" borderColor="#0F8BE2" top="36" bottom="39"></mx:List>
<mx:List width="123" id="listUsuarios" right="10" backgroundColor="#DDEEFF" bottom="39" top="36"></mx:List>
<mx:TextInput left="89" right="214" bottom="9"/>
<mx:Label text="Mensagem:" left="10" bottom="11"/>
<mx:Button label="Enviar" right="144" bottom="9"/>
<mx:Button label="Sair" right="10" bottom="9"/>
</mx:Canvas>Veja que apenas arrastamos os componentes, alteramos cores e formatos, definimos as âncoras etc.
Agora vamos definir algumas funcionalidades básicas no chat. A primeira delas é a definição do nome do usuário. Criamos uma caixa de texto com o valor: "Usuário + enter". Fiz isso de propósito somente para criar uma funcionalidade conhecida no mundo web 2.0. Assim que o usuário selecionar o campo, a mensagem some. Isso é feito assim:
<mx:TextInput id="usuario"
y="8" text="Usuário + Enter" left="76"
focusIn="{if (usuario.text=='Usuário + Enter'){usuario.text=''}}"
focusOut="{if (usuario.text ==''){usuario.text = 'Usuário + Enter'}}"
/>Neste código usamos os evento focusIn (ao ganhar foco) e focusOut (ao perder foco) para preencher a caixa de texto corretamente. Ou seja, quando o usuário clica no campo, o texto some. Se o usuário deixar o campo e ele estiver vazio, preenche com o texto novamente. Veja que o código é bem simples, e bem falho, porque fazer ifs com caracteres de texto (usuario.text=='Usuário + Enter') é de longe a melhor opção... Mas vamos nos contentar com isso agora.
Enquanto o usuário não entrar com o usuário, não iremos exibir a tela de chat para ele. Isso é feito setando a propriedade do canvas que engloba toda a parte do chat para falso. Quando o usuário digitar "enter", nós iremos mudar esta propriedade para true. Veja o código:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" backgroundGradientAlphas="[1.0, 1.0]"
backgroundGradientColors="[#FFFFFF, #FFFFFF]"
creationComplete="OnCreationComplete()"
>
<mx:Script>
<![CDATA[
private function OnCreationComplete():void
{
CanvasChat.visible = false;
}
private function OnUsuarioKeyDown(event:KeyboardEvent):void
{
if (event.charCode == Keyboard.ENTER)
{
usuario.enabled = false;
CanvasChat.visible = true;
}
}
]]>
</mx:Script>
<mx:Label y="10" text="Chat Flex" left="10"/>
<mx:TextInput id="usuario"
y="8" text="Usuário + Enter" left="76"
focusIn="{if (usuario.text=='Usuário + Enter'){usuario.text=''}}"
focusOut="{if (usuario.text ==''){usuario.text = 'Usuário + Enter'}}"
keyDown="OnUsuarioKeyDown(event)"
/>
<mx:Canvas id="CanvasChat" left="1" right="9" top="1" bottom="9"
showEffect="WipeDown"
hideEffect="WipeUp"
>
Nesta implementação, temos diversas novidades. Primeiro é criado o evento creationComplete do Application, chamando o método OnCreationComplete. Este método esconde o canvas que contém o chat, o qual chamamos de "CanvasChat".
Depois é implementado o evento keyDown da caixa de texto onde digita-se o nome de usuário, chamando o método OnUsuarioKeyDown. Neste método, verificamos se a tecla digitada é o Enter e se for, iremos exibir o CanvasChat.
Finalizando, dentro da tag Canvas do CanvasChat, temos duas propriedades chamadas showEffect e hideEffect, que dão um embelezamento natural às telas do Flex.
Assim que o usuário digita o seu nome e tecla enter, precisamos fazer diversas tarefas tais como obter as pessoas da sala e as últimas mensagens postadas, além de anunciar a chegada do novo usuário. Tudo relativo ao chat estará disponível na classe ChatManager.
Então vamos pensar... Esse ChatManager precisa de:
Somente com estes três requisitos será necessário criar mais algumas classes:
A figura a seguir ilustra o processo de comunicação entre as classes.
Com tudo isso criado, podemos partir para a segunda parte do artigo. Ao invés de colar o código destas classes, eu vou deixar o link abaixo para download do código fonte. Comentei bastante o código fonte para um melhor entendimento. Caso tenha dúvidas, fique à vontade para comentar.
Antonio Antunes Banderas
Até agora não entendi porque o Chat:ChatManager estende o UIComponent. Seria um POG?
Daniel Schmitz
Ele é um componente que dispara eventos que se propagam para a aplicação principal. Entendeu?
Antonio Antunes Banderas
humm, mais não entendo porque de estender o UIComponent.....
Antonio Antunes Banderas
o UIComponent é componente gráfico, e estou achando que se trata do maior POG que já vi na vida. E porque ele foi chamado no MXML?
Daniel Schmitz
Oi, bom, seria interessante então alguma outra saída. Alguma idéia??
ps: Classes que herdam de EventDispatcher também disparam eventos, então ao invés de adicionar direto no mxml você iria instanciar a classe. Pode fazer assim e arrumar o POG :)
Leonardo Lima
Olá Daniel, vi que em um tempo atrás voce utilizava o EXTJS para as suas aplicações. Gostaria de saber, se voce migrou para o FLEX ou ainda continua a desenvolver utilizando o EXTJS, e tambem qual deles é o mais aconselhavel para aplicações de pequeno e medio porte?
Abraços....
Daniel Schmitz
Olá, o EXTJS é uma ótima tecnologia, mas exige uma curva de aprendizado maior. Eu recomendo utilizar o Flex, exceto se você domina muito bem o JavaScript (Extjs é javascript). Eu não saí do Ext e fui pro Flex, eu caminho nas duas tecnologias, mas atualmente o Flex está melhor que o EXTJS. Eu não senti o EXTJS evoluir como o Flex, mesmo porque o EXT é GPL3 e o Flex, open source. O Ext é mantido por uma pequena empresa, o Flex pela Adobe, o Flex tem uma ótima IDE e o EXT não, a comunidade Flex é muito maior que a do EXT, o conteúdo para estudo também, enfim são muitas vantagens do Flex em relação ao EXTJS. Mas fique de olho no EXT, ainda pode crescer bastante!
Idemax Adobe Flash Plataform Developer
Se fosse somente ter a necessidade de disparar e escutar eventos, poderia extender EventDispatcher.
Daniel Schmitz
Essa é uma das soluções, até mostrei no comentário acima. O que eu ia fazer é tornar o ChatManager um ícone, ae bastaria arrastar ele pra tela... Igual no delphi... Mas o pessoal vai achar q é POG... fazer o quê neh ... hehehe
Idemax Adobe Flash Plataform Developer
Hahuahuahuahuahaa, até agora não estava entendendo o que era esse tal de POG, então fui no Google e encontrei isso:
http://www.google.com.br/#hl=pt-BR&source=hp&q=POG%3F&btnG=Pesquisa+Google&meta=&aq=f&oq=POG%3F&fp=b03bb2baf7da8838
É isso mesmo, "Programação Orientada a Gambiarras"?! Essa é nova pra mim....
Idemax Adobe Flash Plataform Developer
Ou em inglês, WOP (Workaround-oriented programming)!
Para que não sabe, "workaround" é um termo usado para se resolver um problema de outra forma, NÃO necessariamente uma gambiarra.
Daniel Schmitz
pog é isso:
http://www.google.com/codesearch?q=pog&hl=pt-BR&btnG=Pesquisar+c%C3%B3digo
http://desciclo.pedia.ws/wiki/Pog
Luiz Nogueira
Olá Daniel, em primeiro lugar parabeniza-lo pelo otimo post e aproveitando gostaria de saber se vc usa um software especifico para fazer a modelagem de suas aplicações?
E se podereia me passar o nome do software caso vc use.
Aguardo contato
Atenciosamente,
Luiz Nogueira
Daniel Schmitz
Oi, eu uso o balsamiq mockups, ele é ótimo para criar telas
Luiz Nogueira
Valeu demais pela dica...
Antonio Antunes Banderas
Usa o EventDispatcher. Não instância como MXML, apenas como variável.
POG é Programação Orientada a Gambiarra.
Daniel Schmitz
Isso, também dá. O que eu fiz foi facilitar as coisas. é mais facil adicionar no mxml do que fazer algo como addEventListner. Com certeza o ChatManager pode herdar de EventDispatcher, mas eu prefiro deixar como está para manter a facilidade. Eu agradeço pela atenção, assim os leitores conhecem os dois lados.
Antonio Antunes Banderas
Um cara que escreve Livros sobre Flex me fazer uma coisa destas é praticamente um assassinato as boas práticas.
Alexsandro de Sousa Saraiva
Parabéns pelo artigo Daniel , e desculpe pela pergunta mais com funciona um sistema Real Time utilizando Flex e PHP com esse protocolo RTMP (Real Time Messaging Protocol).
Daniel Schmitz
Ele permite que o Servidor também se comunique com o Cliente. Ou seja, não é preciso criar um Timer que irá fazer uma requisição ao servidor de tempos em tempos. Assim que uma pessoa envia uma mensagem pelo Chat, o servidor se encarrega de redistribir diretamente esta mensagem.
Antonio Antunes Banderas
Procurei na NET e achei estes aqui muito bom sobre RTMP http://blog.mxml.com.br/category/flash-media-server e http://blog.mxml.com.br/compartilhando-camera-e-chat-com-o-flash-media-server
Antonio Antunes Banderas
Achei agora este aqui pronto e funcionando <a href="http://code.google.com/p/flexphpchat/">http://code.google.com/p/flexphpchat/</a>
Antonio Antunes Banderas
Achei agora este aqui pronto e funcionando http://code.google.com/p/flexphpchat/
2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.