Совместная работа с клиентом PlayN с сервером - PullRequest
2 голосов
/ 29 января 2012

Я написал игру в PlayN, которая должна взаимодействовать с JavaEE-сервером через Seam. Прежде всего мне нужна игра, работающая на HTML5.

Текущая проблема - связь между PlayN-клиентом и JavaEE-сервером

1) Сначала я попытался связаться через интерфейс PlayN.net (), обмениваясь информацией с помощью JSON. Так как PlayN работает на порту 8888 и сервере на 8080, у меня правильно возникают проблемы с той же политикой origin.

2) Сейчас я ищу рабочее решение. Какой из них вы бы порекомендовали? У вас есть другие идеи?

a) Я пытаюсь работать с RPC, как описано в Как обрабатывать RPC в клиент-серверной игре PlayN? , используя GWT-syncproxy.

b) Я пытаюсь, чтобы playN работал на том же порту, что и сервер, т. Е. 8080 - поэтому у меня больше нет проблем с той же политикой origin. Вопрос. Может ли приложение HTML5 playN работать на одном и том же порту? Поэтому, когда я запускаю JavaEE-сервер с использованием Eclipse, он также должен запускать веб-приложение PlayN, оба на порту 8080, верно?

Возможно ли это?

в) Наиболее хакерское решение (в настоящее время работает): сервер записывает JSON-String в файл, а клиент playN считывает этот файл.

Что вы рекомендуете? Я хотел бы реализовать решение 2, так как это самое чистое решение, но я не знаю, насколько это сложно и как оно работает.

Спасибо за вашу помощь!

Ответы [ 2 ]

3 голосов
/ 30 января 2012

Мне кажется, проблема в том, что вы «запускаете» PlayN, отдельно от вашего сервера Seam.

Если я вас правильно понял, вы выполняете задачу Maven, чтобы запустить свою игру в формате HTML, а с другой стороны, вы запускаете Jboss (или любой другой сервер Java EE), вам нужно запустить

mvn package

, которая создаст войну игры, а затем опубликует эту войну на вашем сервере Java EE, тогда вы можете без проблем использовать пакет PlayN.net , работающий на одном сервере

2 голосов
/ 31 января 2012

Это то, как мы в настоящее время управляем нашей клиент-серверной связью. Мы используем архитектуру JavaEE без сохранения состояния и предоставляем все как службы REST. Это позволяет нам масштабировать горизонтально, добавляя больше серверов и просто добавляя их к записи кластера в конфигурации Glassfish.

Однако из-за отсутствия отражения или работающей JSON-библиотеки это заставляет нас внедрять метод toJson () в каждый объект передачи данных BY HAND (будьте внимательны с учетом регистра). Мы добавили наш серверный проект в качестве модуля в метапроект PlayN и добавили ядро ​​в качестве зависимости от сервера. Таким образом, вы можете поместить каждый DTO в основной проект (что довольно здорово). Размещение их на сервере приводит к тому, что люди пытаются аннотировать классы как сущности, что приводит к сбою во время сборки html. В настоящее время я думаю о добавлении общего проекта в сборку, как в проектах GWT.

Вот как мы отправляем данные на сервер (для этого примера без какой-либо абстракции сделайте себе одолжение и используйте его):

private void loadMapFromServer() {
    SessionDto session = this.main.getSessionCtrl().getSessionMdl();

    PlayN.net().post("http://localhost:8080/server/rest/map/mapMdl",
        session.toJson(),
        new Callback<String>() {

            @Override
            public void onSuccess(String result) {
                mapMdl = new MapDto();
            }

            @Override
            public void onFailure(Throwable cause) {
                PlayN.log().error("fail " + cause.getMessage());
            }
        });
} 

Обратите внимание, как мы убираем аргумент POST с помощью session.toJson (). Это связано с отсутствующей функцией MIME-типа, и передача строк JSON через GWT не удастся. А вот как это выглядит на сервере:

package com.fact.server;

//I also posted the imports, for clarity.
import com.fact.core.map.MapDto;
import com.fact.core.user.SessionDto;
import com.fact.server.game.map.MapCtrl;
import com.google.gson.Gson;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.log4j.Logger;

@Stateless
@Path("/map")
public class MapSrvs {

@Inject
Logger logger;

@Inject
MapCtrl mapCtrl;

Gson gson = new Gson();

@POST
@Path("/mapMdl/")
@Produces( MediaType.APPLICATION_JSON )
public MapDto getMapMdl(String sessionDtoStr) {
            //logger.info("map was requested: " + sessionDtoStr);

    // Use gson to deserialize the class. Jersey would do this, if PlayN
    // would allow to set a correct MIME type (and @Consumes was set).
    // We could simply write: getMapMdl(SessionDto sessionDto)
    SessionDto sessionDto = gson.fromJson(sessionDtoStr, SessionDto.class);
    if(sessionDto == null) {
        return null;
    }

    // [...] check for a valid session

    MapDto mapMdl = new MapDto();
    mapMdl.foo = "message from server";
    return mapMdl;
}   
}

Это было бы немного лучше, если бы PlayN позволял вам устанавливать тип MIME, чтобы вам не приходилось разыгрывать String с помощью Gson. Однако это работает довольно хорошо. Мы используем Джерси на стороне сервера для обработки всего остального. Чтобы запустить его, мне нужно было поместить в файл web.xml следующее:

<servlet>
    <!-- We need jersey for the REST stuff -->
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>
        com.sun.jersey.spi.container.servlet.ServletContainer
    </servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.fact.server</param-value>
    </init-param>
    <init-param>
        <!-- This took me hours to find :(. It is needed to automatically
        map POJOs to JSON code. -->
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Также Джерси уже включен в Java-EE-Api, так что он работает "из коробки". Надеюсь, это поможет. Если кто-нибудь знает, как выполнить анализ JSON на стороне клиента, посмотрите на этот вопрос: Как преобразовать POJO в JSON в PlayN?

...