"RemoteObject" no Flex 2 com PHP e com Java sem Data Services

É possível no Flex 2, hoje, consumir objetos do PHP tal como era feito no Flex 1.5 com o uso do AMFPHP, assim como é possível consumir objetos Java com o OpenAMF sem a necessidade do Flex Data Services.

Para consumir objetos Java diretamente do Flex 2.0 usa-se o componente RemoteObject, que implementa um conjunto de funcionalidades – entre elas a serialização (“tradução”) dos objetos – do Java para o ActionScript 3.0. No Flex 2 o RemoteObject troca informação com o servidor utilizando um formato chamado AMF3 (ActionScript Message Format 3), de forma que ele pode conversar com qualquer servidor que também saiba receber e enviar objetos (bem como fazer sua serialização) em AMF3. O Flex Data Service é uma aplicação J2EE para comunicação entre a camada de apresentação feita em Flex e a camada de negócios em Java de alta performance, que além de “falar” em AMF3 e ter o RPC (Remote Procedure Call) via RemoteObject oferece funcionalidades de Messaging (colaboração, push de dados, etc) e de Data Management (sincronização de objetos, clientes off-line, etc). O Flex também pode se comunicar com serviços em SOAP (WebServices) ou via HTTP.

Contudo, nem sempre é possível utilizar um servidor capaz de se comunicar em AMF3, como o Flex Data Services ou o ColdFusion.

A versão anterior do Flex (versão 1.5) era baseada no ActionScript 2.0, cujo formato para troca de dados do RemoteObject era o AMF0 (não existe AMF1 nem AMF2). Para esse formato de troca de mensagens há outros servidores que podem ser utilizados, como o OpenAMF (para Java) e o AMFPHP (para PHP). O ColdFusion já conversava nativamente com o Flex 1.5, assim como faz com o Flex 2.

É esperado que essas tecnologias (OpenAMF e AMFPHP) sejam atualizados para se comunicar também em AMF3 e conversar nativamente com o Flex 2, mas ainda assim é possível utilizar as versões existentes do OpenAMF e AMFPHP que se comunicam apenas via AMF0 com o Flex 2. O que precisa ser feito, basicamente, é dizer para o Flex que os dados que serão trocados estarão no formato AMF0, e não no formato AMF3.

Como o RemoteObject só conversa em AS3, podemos utilizar a classe

1
flash.net.NetConnection

que igualmente pode ser utilizada para se comunicar com o servidor e contém uma propriedade (

1
objectEncoding

) indicando o encoding dos objetos trocados com o servidor. Essa variável é static e os possíveis valores para ela estão definidos na classe

1
flash.net.ObjectEncoding

:

1
NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0;

Assim, podemos criar um novo serviço regido pela classe

1
NetConnection

:

1
public var service:NetConnection = new NetConnection();

E definir qual o endpoint ele acessará:

1
service.connect("http://localhost:8080/TesteAMF/amfgateway");

A partir daí, basta usar o método

1
call()

de nosso serviço (que é um

1
NetConnection

) para chamar os métodos no servidor. Nesse momento vamos também definir os responsáveis por tratar a resposta do servidor, utilizando a

1
flash.net.Responder

:

1
service.call("Teste.getArrayList", new Responder(resultHandler, faultHandler));

Abaixo um exemplo completo em Flex 2.0 que se consome uma classe Java via AMF0:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    initialize="initApp()">

    <mx:Script>
    <![CDATA[
    import flash.net.ObjectEncoding;
    import flash.net.NetConnection;
    import mx.collections.ArrayCollection;
    import mx.controls.Alert;

    // O serviço poderá ser chamado de qualquer lugar.
    public var service:NetConnection = new NetConnection();

    [Bindable]
    public var meses:ArrayCollection;

    public function initApp():void
    {
        // define o encoding para amf0
        NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0;

        // Conecta no servidor amf. O endereço é o "endpoint" do RemoteObject
        service.connect("http://localhost:8080/TesteAMF/amfgateway");
    }

    public function getArrayList():void {
        // Chama o método getArrayList da classe Teste.
        // Define um handler para o o resultado e um para a falha.
        service.call("Teste.getArrayList", new Responder(resultHandler, faultHandler));
    }

    public function resultHandler(result:Array):void
    {
        meses = new ArrayCollection(result);
    }

    public function faultHandler(fault:String):void
    {
        Alert.show('Erro');
    }

    ]]>
    </mx:Script>

    <mx:RemoteObject />
    <mx:ComboBox dataProvider="{meses}" />

    <mx:Button buttonDown="getArrayList()" label="Pegar dados do servidor" />

</mx:Application>

É possível até mesmo conectar à serviços disponíveis em uma instalação do Flex 1.5. Assim, novas aplicações podem ser desenvolvidas em Flex 2 para aproveitar os novos recursos de interface, até o servidor ser efetivamente migrado para o Flex Data Services.

Esse é um exemplo simples de integração, uma prova de conceito. Boa parte da lógica de conexão com o serviço remoto pode ser encapsulada em uma classe para ser mais fácil de trabalhar. Já há um componente muito interessante chamado RemoteObjectAMF0 que visa justamente isso.

A prática de consumo e troca de objetos é encorajada em relação ao WebService e à serviços HTTP. Além dos ganhos de performance e escalabilidade, há troca (e serialização) dos objetos nativos das linguagens. Prefira o uso do RemoteObject, aproveite os benefícios do AMF.


8 comentários

  1. Igor Costa em 28.nov.06 às 11:00 pm

    Gostei do post.
    Mas só uma dica que na verdade Você pode usar o formato AMF3 sem o DataService, sem precisar dizer que o formato seja AMF0.
    Em um projeto usei o Arp que já faz isso.
    http://svn1.cvsdude.com/osflash/arp/trunk/as3/org/osflash/arp/AMF0Service.as

  2. Igor Costa em 28.nov.06 às 11:05 pm

    Só uma correção AMF0, Entendi errado.

  3. Fabio Terracini em 29.nov.06 às 1:42 am

    É possível utilizar o AMF3 sem o DataService, como escrevi acima. Basta utilizar um outro servidor que se comunique em AMF3, como o ColdFusion e como o planejado para o OpenAMF, por exemplo.

    Mas para se comunicar em AMF0, é *imperativo* que se explicite o uso de tal. O ARP 3 também faz isso, mas o faz de forma transparente (veja a classe RemotingConnection, usada pelo AMF0Service, que contém a definição de uso do AMF0).

  4. Leonardo França em 29.nov.06 às 12:54 pm

    Parabens pelo artigo Fabio, vemos nas listas que a galera ainda se confunde um pouco sobre o AMF0 e AMF3. Estou testando uma implementação em PHP5 que já suporta o AMF3, o SabreAMF

    Ate mais
    Leonardo França

  5. Eder roger de souza em 21.dez.06 às 11:12 am

    vc poderia me ajudar a criar desde o começo tipo instalando e configurarno o openAmf com o tomcat 5.5 depois criando as classes java simples so para testes a comfiguraçao do config-xml do opemamf pra reconhecer as classes java e por ultimo o acesso via flex 2 desses dados via AMF sem o data services!!

    Por favor se puder me ajudar!!
    abraço fique com Deus!

  6. Fabio Terracini em 22.fev.07 às 3:08 pm

    Eder, há bons tutoriais na Internet sobre isso, inclusive no site da Adobe e alguns exemplos na documentação. Contudo, houve uma conversa na lista FlexDev justamente sobre isso que pode lhe auxiliar: http://groups.google.com/group/flexdev/browse_thread/thread/d12bf1db1d294645

  7. Gumercindo em 29.mar.07 às 4:48 pm

    ae pessoal, alguem sabe como eu faço um master-detail com OpenAMF? tipo via http eu tava conseguindo, pq eu gerava um xml e via como pegar mas agora com o OpenAMF eu nao to conseguindo, eu fiz duas classes no java tipo usuario e endereços sendo que o usuario pode ter varios enderecos, isso é um exemplo, mas tipo eu ate listo os usuarios mas nao consigo obter os enderecos, alguem pode me ajudar?

Trackbacks

  1. A evolução da Internet - Flash | MXStudio

Deixe Seu Comentário