Как стать автором
Обновить

Первые шаги в разработке Flash игры. Делаем Backend на AMFPHP

Время на прочтение7 мин
Количество просмотров4.1K
Социальные игры — очень неустойчивая, но в то же самое время очень требовательная и интересная отрасль разработки.

Когда начинаешь работать с новым проектом, ты всегда находишься между двух огней — с одной стороны нужно делать все очень быстро, т.к. скорее всего, несколько твоих конкурентов тоже приступили к разработке, и наступают тебе на пятки, а с другой стороны ты должен делать так, что если завтра посещаемость увеличится в 5 раз, твои сервера должны это выдержать.

Но это все лирика, а лиричности и романтики в нашей жизни хватает, поэтому приступим сразу к техническим деталям.




AMF
Это бинарный формат, использующий сериализованные ActionScript объекты для кроссдоменного общения.В принципе, это достаточная информация, для понимания того, зачем его использовать, но для тех, кто хочет узнать больше, есть википедия, цитировать которую смысла я не вижу.

AMFPHP
В качестве библиотеки парсинга AMF используется AMFPHP, потому что:
1. Его можно быстро установить
2. Не требует установки дополнительных расширений на сервере
3. Opensource, и написан на PHP, что помогает быстро в нем разобраться и изменить его поведение так, как надо (это крайний случай, но возможность все равно должна быть)
3. Не привязан к какому-либо фреймворку и сам не является фреймворком
4. Нативно парсит JSON
5. Содержит встроенный профайлер.

Первичная настройка.
Для начала введем некоторые условности. Доступ к проекту осуществляется по аресу http://game/. DOCUMENT_ROOT для нашего проекта — это папка www, приложение лежит в папке app, а все сторонние библиотеки в папке lib. Модели находятся в папке app/model, а абстрактные классы в папке app/model/abstract, контроллеры в папке /app/controller. Если Вы решили слепо следовать моему руководству, то советую эти папки создать.

Процесс поднятия сервера.
0. Создаем файл www/gateway.php такого содержания:
<?php<br/>require_once '../app/config.php';<br/>require_once 'amfphp/gateway.php';

1. Скачиваем AMFPHP, распаковываем его, кладем папку core и все файлы, которые находятся в корне (кроме .htaccess) в папку lib/amfphp

2. Создаем файл app/config.php следующего содержания:
<?php<br/>// Главный конфиг проекта<br/>define('ROOT_DIR', '/var/www/game/'); // Корневая папка для файлов проекта <br/>define('LOG_DIR', ROOT_DIR . 'log/'); // Папка для логов<br/>define('GAME_PLATFORM', 'development'); // Игровая платформа<br/>$paths = array(<br/>    '.',<br/>    ROOT_DIR . 'lib',<br/>    ROOT_DIR . 'app'<br/>);<br/>set_include_path(implode(PATH_SEPARATOR, $paths));

3. В файле lib/amfphp/globals.php присваиваем переменной $servicesPath значение ROOT_DIR. «app/controller/»

4. Создаем файл app/model/Response.php со следущим содержанием:
<?php
<?php<br/>abstract class Response<br/>{<br/>    protected $error;<br/>    protected $content = array();<br/> <br/>    public function __construct(array $content = null)<br/>    {<br/>         if (isset($content)) {<br/>            $this->content = $content;<br/>         }<br/>    }<br/> <br/>    public function addContent($content)<br/>    {<br/>        if (!is_array($content)) {<br/>           return false;<br/>        }<br/>        foreach ($content as $name => $data) {<br/>           $this->content[$name] = $data;<br/>        }<br/>    }<br/> <br/>    public function getData()<br/>    {<br/>        return array(<br/>     'error' => $this->error,<br/>            'response' => $this->content,<br/>        );<br/>    }<br/>}<br/> <br/>class ErrorResponse extends Response<br/>{<br/>    public function __construct(array $content = null)<br/>    {<br/>        parent::__construct($content);<br/>        $this->error = 1;<br/>    }<br/>}<br/> <br/>class SuccessResponse extends Response<br/>{<br/>    public function __construct(array $content = null)<br/>    {<br/>        parent::__construct($content);<br/>        $this->error = 0;<br/>    }<br/>}

В этом файле описываются два различных варианта ответа: ответ с ошибкой (ErrorResponse) и «удачный» ответ (SuccessResponse)

5. Создаем оболочку для контроллера ( файл app/model/abstract/AbstractAMFController.php )<?php
<?php<br/>require_once 'model/Response.php';<br/> <br/>class AbstractAMFController { <br/> <br/>    protected $controller;<br/> <br/>    public function __construct($controllerName)<br/>    {<br/>        $this->controller = new $controllerName();<br/>    }<br/> <br/>    protected function methodWrapper($method, $data){    <br/>        try{ <br/>                $result = $this->controller->$method($data);<br/>                $response = new SuccessResponse();<br/>                $response->addContent($result);<br/>            } catch (Exception $e){<br/>                $response = new ErrorResponse($e->getMessage().'\n'.$e->getTraceAsString());<br/>            }<br/>        } <br/>        return $response->getData();<br/>    } <br/>}

Эта оболочка вызывает метод контроллера, указанного в конструкторе, а если вдруг внутри метода случился экшепшн, то формирует запрос с ошибкой и выдает его. Эта оболочка удобна тем, что в будующем сможет хранить внутри себя кучу кода (например логгирование, автоматическое создание класса игрока, трейсы, да и еще много чего, нет смысла сейчас перечислять)

6. Создаем файл app/controller/wrappers.php
class Game extends AbstractAMFController { <br/>    public function __construct(){<br/>        parent::__construct('GameController');<br/>    }<br/> <br/>    public function hello($data){<br/>        return $this->methodWrapper('hello', $data);<br/>    }<br/>}

Здесь будут храниться врапперы методов. Дело в том, что AMFPHP не хочет работать с магической функцией __call, поэтому приходится писать немного больше кода, чем хотелось бы

7. Ну вот, финальный аккорд. Создаем файл app/controller/Game.php
class GameController{<br/> <br/>    public function hello($data){<br/>        return 'hello';<br/>    }<br/>}<br/>include 'wrappers.php';

Теперь можно открыть браузер (он лежит в архиве с AMFPHP в папке browser, адрес — http://game/gateway.php, метод — hello.Вуаля, Вам должно выдать что-то вроде {«error»:0, «response»:«hello»}
Ну все, теперь сервер готов, и можно начинать реализовывать первые вызовы. Но это все потом, а сейчас допивать чай и идти домой, почти 9, а я все еще на работе :).
Теги:
Хабы:
Всего голосов 39: ↑33 и ↓6+27
Комментарии25

Публикации

Работа

PHP программист
77 вакансий

Ближайшие события