2010-01-17 4 views
2

Flash + AMFPHP - отличная комбинация. Но бывают случаи, когда Flash Remoting с NetConnection не является подходящим инструментом по разным причинам. У Роба была отличная статья об этом некоторое время назад: http://www.roboncode.com/articles/144AMFPHP: Сериализация Flash-объектов через HTTP без шлюза

У него также есть хороший пример того, как доставить AMF на HTTP-запрос, без пакета POST и AMF-запроса, чтобы вызвать функцию, которую NetConnection отправляет, используя Zend_AMF ,

// Include the Zend Loader 
include_once 'Zend/Loader.php'; 
// Tell the Zend Loader to autoload any classes we need 
// from the Zend Framework AMF package 
Zend_Loader::registerAutoload(); 

// Create a simple data structure 
$data = array('message' => 'Hello, world!'); 
// Create an instance of an AMF Output Stream 
$out = new Zend_Amf_Parse_OutputStream(); 
// We will serialize our content into AMF3 for this example 
// You could alternatively serialize it as AMF0 for legacy 
// Flash applications. 
$s = new Zend_Amf_Parse_Amf3_Serializer($out); 
$s->writeObject($data); 

// Return the content (we have found the newline is needed 
// in order to process the data correctly on the client side) 
echo "\n" . $out->getStream(); 

Мне очень нравится этот подход и очень хотелось бы воспроизвести его с помощью AMFPHP. Почему AMFPHP, спросите вы? В «новейшей» версии используется amf-ext, расширение C PHP, для сериализации и десериализации данных. Это намного быстрее, чем использование php-метода ZendAMF.

Конечно, я уже играл с AMFPHP и пытался построить необходимые объекты и использовать класс Serializer. Я даже получил действительную строку AMF, но реальные данные всегда были обернуты «пакетом методов», который сказал получателю, что это был ответ на вызов «Service.method».

Итак, есть способ сериализовать объекты Flash напрямую, без оболочки шлюза и метода, в AMFPHP?

Спасибо.

ответ

4

Хорошо, теперь оно работает.

Это немного сложнее, чем решение Zend_AMF, но намного быстрее. Вот мой код:

$data = array('message' => 'Hello, world!'); 

// Create the gateway and configure it 
$amf = new Gateway(); 
Amf_Server::$encoding = 'amf3'; 
Amf_Server::$disableDebug = true; 

// Construct a body 
$body = new MessageBody("...", "/1", array()); 
$body->setResults($data); 
$body->responseURI = $body->responseIndex . "..."; 

// Create the object and add the body 
$out = new AMFObject(); 
$out->addBody($body); 

// Get a serializer and use it 
$serializer = new AMFSimpleSerializer(); 
$result = $serializer->serialize($out); 

Как вы видите, есть новый класс AMFSimpleSerializer который я построил:

class AMFSimpleSerializer extends AMFSerializer 
{ 
    function serialize(&$amfout) 
    { 
     $encodeCallback = array(&$this,"encodeCallback"); 

     $body = &$amfout->getBodyAt(0); 

     $this->outBuffer = ""; 
     $this->outBuffer .= amf_encode($body->getResults(), $this->encodeFlags, $encodeCallback); 
     $this->outBuffer = substr($this->outBuffer, 1); 

     return $this->outBuffer; 
    } 
} 

Этот класс работает только если установлен amfext, но может быть легко модом использовать PHP процесс enocding. Я не реализовал его, потому что я построил это на сильно измененной версии AMFPHP.

Надеюсь, что я заменил все классы из своего кода там, где есть настоящие аналоги AMFPHP. Я постараюсь проверить это завтра и обновить этот ответ, если это необходимо.

После того, как я был закончен, я узнал, что теперь практически ничего из AMFPHP не осталось в классе, это всего лишь вызов amf_encode и удаление первого байта, чтобы клиент мог понять, что он получает.

Простая, простая, быстрая.

1

Это упрощенная версия, которая не нуждается в amfext:

require_once('amfphp/core/amf/app/Gateway.php'); 
require_once(AMFPHP_BASE . 'amf/io/AMFSerializer.php'); 

$data = array('message' => 'Hello, world!') 

$serializer = new AMFSerializer(); 
$serializer->writeAmf3Data($data); 

print $serializer->outBuffer; 

Нет новой строки и подстроки необходимо. AMFPHP 1.9, Flex 3.4.