如何处理客户端 - 服务器PlayN游戏中的RPC?
我想使用PlayN创建一个客户端/服务器卡片游戏,例如心。虽然我主要关注HTML5输出,但我最好喜欢在输出平台不可知的情况下,以防我决定在将来制作Android客户端。我应该如何处理RPC机制?如何处理客户端 - 服务器PlayN游戏中的RPC?
这些是我想过的选项:用GET()/后的RPC()方法
- 使用JSON - 写一个接受/返回JSON一个servlet,使客户端代码的所有版本使用它。这似乎是可行的,但我担心JSON的冗长。一旦我得到Hearts的工作,我想继续进行更复杂的游戏,我担心JSON会导致在客户端和服务器之间来回传递大量超过必要的消息。我实际上并不知道如何在Java中使用JSON,但我认为这是可行的。我的假设是否在线? Java如何与JSON协同工作?
- 继续使用GWT-RPC。我可以通过在我的核心(平台不可知的)构造函数中使用异步服务接口,并在我的HTML main()中传入由
GWT.create(MyService.class)
(或至少包装它)生成的GWT异步接口。我不知道这对非HTML版本有效。我可以直接从客户端Java代码使用GWT-RPC吗? - 使用其他形式的RPC。有什么建议么?
对于Java和Android平台上的GWT RPC,我目前正在尝试使用gwt-syncproxy为GWT RPC方法提供Java客户端访问,并且我正在使用Guice,杜松子酒和RoboGuice他们各自的目标平台为实例化的Game对象注入适当的异步服务实例。
在一个PlayN项目的核心/ pom.xml中,我包括以下依赖坐标作为需要从GIN /吉斯/ RoboGuice支持DI:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
然后,添加@Inject注释任何领域具体实施游戏里面:
public class TestGame implements Game {
@Inject
TestServiceAsync _testService;
...
}
在HTML/pom.xml中,我包括杜松子酒的依赖坐标:
<dependency>
<groupId>com.google.gwt.inject</groupId>
<artifactId>gin</artifactId>
<version>1.5.0</version>
</dependency>
我创建TestGameGinjector和TestGameModule类:
TestGameGinjector.java
@GinModules(TestGameModule.class)
public interface TestGameGinjector extends Ginjector {
TestGame getGame();
}
TestGameModule.java
public class TestGameModule extends AbstractGinModule {
@Override
protected void configure() {
}
}
因为在那一刻,我只注射TestServiceAsync接口,我不需要在TestGameModule.configure()方法中放置任何实现;杜松子酒通过GWT.create()为我管理AsyncServices的实例化。
我加入以下到TestGame.gwt.xml
<inherits name='com.google.gwt.inject.Inject'/>
最后,我做了如下修改TestGameHtml。java
public class TestGameHtml extends HtmlGame {
private final TestGameGinjector _injector = GWT.create(TestGameGinjector.class);
@Override
public void start() {
HtmlPlatform platform = HtmlPlatform.register();
platform.assetManager().setPathPrefix("test/");
PlayN.run(_injector.getGame());
}
}
而且这几乎涵盖了PlayN的HTML5平台。
对于Java平台,我添加以下的依赖坐标,爪哇/ pom.xml中:
<dependency>
<groupId>com.gdevelop.gwt.syncrpc</groupId>
<artifactId>gwt-syncproxy</artifactId>
<version>0.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0-rc2</version>
</dependency>
请注意,谷歌代码GWT-syncproxy项目不包含一个pom.xml。我有一个mavenized版本的gwt-syncproxy分叉和可通过git在https://bitbucket.org/hatboyzero/gwt-syncproxy.git。您应该可以克隆它,运行mvn clean package install以将其导入您的本地Maven存储库。
不管怎么说,我创建了Java平台的TestGameModule.java如下:
public class TestGameModule extends AbstractModule {
@Override
protected void configure() {
bind(TestServiceAsync.class).toProvider(TestServiceProvider.class);
}
public static class TestServiceProvider implements Provider<TestServiceAsync> {
public TestServiceAsync get() {
return (TestServiceAsync) SyncProxy.newProxyInstance(
TestServiceAsync.class,
Deployment.gwtWebPath(), // URL to webapp -- http://127.0.0.1:8888/testgame
"test"
);
}
}
}
而且我修改TestGameJava.java如下:
public class TestGameJava {
public static void main(String[] args) {
Injector _injector = Guice.createInjector(new TestGameModule());
JavaPlatform platform = JavaPlatform.register();
platform.assetManager().setPathPrefix("test/images");
PlayN.run(_injector.getInstance(TestGame.class));
}
}
我经历了类似的活动与去Android平台和RoboGuice--没有涉及到很多细节,相关变更/片段如下:
pom.xml d ependencies
<dependency>
<groupId>com.gdevelop.gwt.syncrpc</groupId>
<artifactId>gwt-syncproxy</artifactId>
<version>0.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.roboguice</groupId>
<artifactId>roboguice</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0-rc2</version>
<classifier>no_aop</classifier>
</dependency>
TestGameApplication.java
public class TestGameApplication extends RoboApplication {
@Override
protected void addApplicationModules(List<Module> modules) {
modules.add(new TestGameModule());
}
}
TestGameModule.java
public class TestGameModule extends AbstractModule {
@Override
protected void configure() {
bind(TestServiceAsync.class).toProvider(TestServiceProvider.class);
}
public static class TestServiceProvider implements Provider<TestServiceAsync> {
public TestServiceAsync get() {
return (TestServiceAsync) SyncProxy.newProxyInstance(
TestServiceAsync.class,
Deployment.gwtWebPath(), // URL to webapp -- http://127.0.0.1:8888/testgame
"test"
);
}
}
}
TestGameActivity.java
public class TestGameActivity extends GameActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
final Injector injector = ((RoboApplication) getApplication()).getInjector();
injector.injectMembers(this);
super.onCreate(savedInstanceState);
}
@Override
public void main(){
platform().assetManager().setPathPrefix("test/images");
final Injector injector = ((RoboApplication) getApplication()).getInjector();
PlayN.run(injector.getInstance(TestGame.class));
}
}
这是一个如何在我的项目中获得Gin/Guice/RoboGuice + GWT的快速和肮脏的破坏,并且我已经验证它可以在Java和HTML平台上很好地工作。
无论如何,有GWT的方法来提供RPC呼叫到多个PlayN平台:)。
我继续更新我的回答有点,因为我已经成功地制定出了很多扭结的怎么最近做到这一点... – hatboyzero 2012-02-03 19:45:10
这听起来像我可以做我的事与GWT RPC和采取这种做法,如果/当我想要支持非HTML输出模式时。感谢您的详细回复! – 2012-02-18 22:39:39
没问题 - 很高兴成为服务:) – hatboyzero 2012-02-23 20:41:11
不是一个完整的答案,但有一点:Java与Json很好地协作,但所有好的Json库在PlayN下都被破坏了。我今天刚刚发布了一个问题,因为我们正在使用Jersey和EE堆栈中的其他一些东西将我们的服务器构建为无状态的REST应用程序。 http://stackoverflow.com/questions/9045455/how-do-i-convert-a-pojo-to-json-in-playn 这eneables我们分享的DTO,并有类型安全的回调和投射 使用您的GWT方法可能打破Java构建,然后你可以坚持到GWT,并使用一些画布框架。 – iuiz 2012-01-28 17:11:07