Herberth Amaral Software development adventures

15Dec/091

Usando o SabreAMF com o CakePHP

O AMF é um formato aberto de comunicação do Flash. É o formato preferido para tais aplicações por possuir diversas vantagens, sendo que a principal delas é a velocidade, já que o AMF não precisa ser deserializado como o XML e o JSON.

Por ser um formato aberto, ele pode ser implementado em qualquer linguagem. Há várias implementações para o PHP, sendo que as mais notáveis são o AMFPHP, Zend_AMF e o SabreAMF.

Neste tutorial, eu mostrarei como desenvolver aplicações em PHP com o framework CakePHP que se comunicam com o Flash (usando a plataforma Flex 3) através da biblioteca SabreAMF.

1- Baixando e instalando os componentes

1 - Baixe os CakePHP 1.2.5 no site do CakePHP e o SabreAMF no Google Code.

2- Instale o CakePHP de forma que ele fique disponível em http://localhost/cakeflex.

3 - Descompacte o SabreAmf em app/vendors/SabreAMF

2 - Colocando os dois para trabalhar

Para fazer com que o CakePHP trabalhe de forma transparente com o SabreAMF, é necessário criar um componente para o CakePHP.

Para tal, vamos criar o nosso componente: (salve-o em app/controllers/components/sabre_amf.php)

<?php

set_include_path(APP.'vendors' . PATH_SEPARATOR . get_include_path());
App::import('Vendor', 'SabreAMF_CallbackServer', array('file'=>'SabreAMF/CallbackServer.php'));

class SabreAmfComponent extends Object {

    function startup(&$controller) {
        if ($controller->action == 'gateway') {
            global $_cakeController;
            $_cakeController = $controller;
            Configure::write('debug', 0);
            $controller->autoRender = false;
            $server = new SabreAMF_CallbackServer();
            $server->onInvokeService = array($this,'amfCallBack');
            $server->exec();
            exit;
        }
		else if(empty($controller->amfExclude) ||
                        !in_array($controller->action,$controller->amfExclude))
            exit();
    }

    function amfCallBack($service, $method, $data) {
        global $_cakeController;
        $res = null;
        if ($_cakeController) {
            if (strpos($method, "_") !== 0) {
                if (method_exists($_cakeController, $method)  and
                    !in_array($_cakeController->action,$_cakeController->amfExclude))
                	$res = call_user_func_array( array( $_cakeController, $method ), $data );
                else
                    $res = "Action nao encontrada.";
            } else
                $res = "Nome de metodo invalido.";
        }
		else
            $res = "Controller nao encontrado.";
        return $res;
    }
}
?>

O que nós fizemos acima foi redirecionar todas as chamadas à action 'gateway' do controller para nosso gateway do SabreAMF.

Agora, um exemplo de como utilizar isso em um controller:

<?php
// app/controllers/teste_amf_controller.php
class TesteAmfController extends AppController
{
	var $components = array('SabreAmf');

    function hello($nome){
        $ret = "Olá, ".$nome."! agora são: ".date("H:i:s")." horas";
        return  $ret;
	}
}
?>

Nosso server side não estaria completo sem o nosso model. No meu caso, como é só uma demonstração, eu não quero criar uma tabela no banco de dados. Portanto, eu crio o meu model dessa forma:

<?php
// app/models/teste_amf.php
class TesteAmf extends AppModel
{
    var $useTable = false;
}
?>

Para demonstrar nosso código funcionado, nada melhor que uma aplicação Flex. Segue abaixo, um exemplo de como a configuração criada acima pode ser usada no Flex:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

	<mx:RemoteObject
		endpoint="http://localhost/cakeflex/teste_amf/gateway"
		id="rmoTeste"
		source=""
		destination="minhaApp"
		result="rmoTesteResult(event)"
		fault="rmoTesteFail(event)"
		showBusyCursor="true"
		/>

	<mx:Button label="Hello!" click="rmoTeste.hello('Herberth')"/>
	<mx:Script>
		<![CDATA[
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			import mx.controls.Alert;

			public function rmoTesteResult(e:ResultEvent):void
			{
				Alert.show(e.result.toString());
			}

			public function rmoTesteFail(e:FaultEvent):void
			{
				Alert.show("Fail!");
			}
		]]>
	</mx:Script>
</mx:Application>

4 - Conclusão

O resultado final deve ficar parecido com isso:

hello_flex

É possível retornar tipos mais complexos para serem usados em tipos mais complexos (tipo AdvancedDataGrid), mas irei abordar tal aplicação mais futuramente.

5 - Referências

É isso aí pessoal. Até a próxima!

  • Share/Bookmark
25Nov/091

Hello World de Python + OpenGL

Há quase um ano eu comecei a estudar Python e gostei de muitas características da linguagem, como o fato de ser de altíssimo nível (very high level), sintaxe clara e elegante, poderosa, portável,  super rápida,fácil aprendizado e um dos melhores: tipagem forte e dinâmica.

Gostei tanto que comecei a fazer alguns trabalhos de faculdade (mais notavelmente trabalhos nas áreas de Banco de Dados, Inteligência Artificial e, recentemente, Computação Gráfica) usando Python. Para vários trabalhos eu encontrei snippets de código, mas não foi tão fácil para CG usando OpenGL. Por isso, resolvi postar esse pequeno exemplo de como usar Python (na versão 2.6.4) + OpenGL.

Primeiro, baixe o PyOpenGL em http://pypi.python.org/pypi/PyOpenGL, descompacte e execute os comandos para instalar o pacote:´

python setup.py build
python setup.py install

Lembrando que se você estiver no Windows, o executável do Python deverá estar no seu PATH.

Instalado o pacote, é hora de fazer um teste. Abra o shell do Python e digite isso:

>>> import OpenGL

Se não aparecer nenhuma mensagem de erro, o pacote do OpenGL foi instalado com sucesso. Agora é hora de uma pequena demonstração de uso do PyOpenGL:

from OpenGL.GL import *
from OpenGL.GLUT import *

def display():
  glClear (GL_COLOR_BUFFER_BIT)
  glBegin (GL_POLYGON)
  glVertex2f(0.4,0.4)
  glVertex2f(0.01,0.01)
  glVertex2f(0.3,0.6)
  glEnd()
  glFlush()
glutInit ()
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize (250,250)
glutInitWindowPosition (0,0)
glutCreateWindow ("Testando o PyGraphs")
glClearColor (0.0, 0.0, 0.0, 0.0)
glOrtho (0.0, 1.0, 0.0, 1.0, -1.0, 1.0)
glutDisplayFunc(display)
glutMainLoop ()

A API do OpenGL pro Python segue as mesmas convenções da API para C/C++. Então, todo e qualquer exemplo que você achar na Web em C/C++ é compatível com o Python (as vezes com algumas pequenas alterações de tipos, mas o nome das funções continua o mesmo).

Se tudo estiver ok, você deverá ver algo parecido com a seguinte figura:

pygraph

Alguns links úteis:

Acho que é isso. Até a próxima!

  • Share/Bookmark
21Nov/096

Hello world!

Buenas!

Finalmente eu cumpri a promessa de criar meu blog. Já estava na hora, né? ;)

Aqui eu quero fazer jus à palavra/expressão Web Log: pretendo postar sobre meu cotidiano, principalmente a parte envolvendo tecnologia.

Atualmente o meu foco é desenvolvimento para a Web e isso inclui tecnologias como JavaScript, .NET, Flex, PHP, Python e seus respectivos frameworks que eu estudo: jQuery, ASP.NET MVC, PureMVC, CodeIgniter e CakePHP, Django.

Além de tecnologias, metodologias de desenvolvimento têm feito parte do meu dia-a-dia. Então é possível que eu fale muito sobre Scrum, XP, Lean e vários conceitos agregados:  TDD, Pair Programming, Continuous Integration, User Stories e etc.

Hope you enjoy! :D

  • Share/Bookmark
Tagged as: , 6 Comments