首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从PlayN客户端与服务器进行协作

从PlayN客户端与服务器进行协作
EN

Stack Overflow用户
提问于 2012-01-29 22:10:59
回答 2查看 665关注 0票数 2

我已经用PlayN写了一个游戏,它必须通过Seam与JavaEE服务器通信。首先,我只需要在HTML5中运行游戏。

当前的问题是播放客户端和JavaEE服务器之间的通信

1)首先,我尝试通过PlayN.net()接口进行通信,使用JSON交换信息。由于PlayN在端口8888上运行,而服务器在8080上运行,因此我正确地遇到了同源策略的问题。

2)现在我正在寻找一个可行的解决方案。你推荐哪一种?你还有其他想法吗?

a)我正在尝试使用How to handle RPCs in client-server PlayN game?中描述的RPC,使用GWT-syncproxy。

b)我试着让playN和服务器运行在同一个端口上,比如8080 --这样同源策略就不会再有问题了。问: HTML5 playN应用程序可以在同一端口上运行吗?因此,当我使用Eclipse启动JavaEE-Server时,它也应该启动PlayN web应用程序,两者都在端口8080上,对吗?

这个是可能的吗?

c)最棘手的解决方案(目前有效):服务器将JSON-String写入一个文件,然后playN客户端将该文件读出。

你有什么建议吗?我想实现解决方案2,因为它是最干净的解决方案,但我不知道它有多难以及它是如何工作的。

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-30 20:35:25

我认为问题在于你正在“运行”PlayN,独立于你的Seam服务器。

如果我没理解错的话,您可以执行Maven任务来运行您的游戏作为HTML,而另一方面您运行Jboss (或任何Java服务器),您应该做的是运行

mvn package

它将创建游戏的war,然后将该war发布到您的Java服务器上,然后您可以毫无问题地使用PlayN.net包,在单个服务器上运行

票数 3
EN

Stack Overflow用户

发布于 2012-01-31 06:33:57

这就是我们目前处理客户端/服务器通信的方式。我们使用无状态JavaEE架构,并将所有内容都作为REST服务提供。这允许我们通过添加更多的服务器并简单地将它们添加到Glassfish配置中的集群条目来进行水平扩展。

然而,由于缺少反射或有效的JSON lib,它迫使我们在每个数据传输对象中手动实现toJson()方法(要区分大小写)。我们将服务器项目作为模块添加到PlayN元项目中,并将核心作为依赖项添加到服务器中。所以你可以把每个DTO放在核心项目上(这是非常棒的)。将它们放在服务器上会导致人们试图将类注释为实体,这将导致在html构建期间失败。我目前正在考虑将共享项目添加到构建中,就像在GWT项目中一样。

这就是我们向服务器发送数据的方式(对于这个例子,没有任何抽象,帮你自己一个忙,实现一个):

代码语言:javascript
复制
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());
            }
        });
} 

注意我们是如何用session.toJson()来破坏POST参数的。这是因为缺少MIME类型功能,通过GWT传递JSON字符串将失败。这是它在服务器上的样子:

代码语言:javascript
复制
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类型,这样您就不必使用Gson转换字符串,这会更好一些。然而,这种方法工作得很好。我们在服务器端使用Jersey来处理所有其他的事情。要让它运行,我必须将以下内容放入web.xml:

代码语言:javascript
复制
<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>

此外,Jersey已经包含在Java-EE-Api中,因此它可以开箱即用。我希望这能帮到你。如果有人知道如何进行客户端JSON解析,请查看这个问题:How do I convert a POJO to JSON in PlayN?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9053798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档