2012-01-28 149 views
9

我想使用PlayN創建一個客戶端/服務器卡片遊戲,例如心。雖然我主要關注HTML5輸出,但我最好喜歡在輸出平臺不可知的情況下,以防我決定在將來製作Android客戶端。我應該如何處理RPC機制?如何處理客戶端 - 服務器PlayN遊戲中的RPC?

這些是我想過的選項:用GET()/後的RPC()方法

  1. 使用JSON - 寫一個接受/返回JSON一個servlet,使客戶端代碼的所有版本使用它。這似乎是可行的,但我擔心JSON的冗長。一旦我得到Hearts的工作,我想繼續進行更復雜的遊戲,我擔心JSON會導致在客戶端和服務器之間來回傳遞大量超過必要的消息。我實際上並不知道如何在Java中使用JSON,但我認爲這是可行的。我的假設是否在線? Java如何與JSON協同工作?
  2. 繼續使用GWT-RPC。我可以通過在我的核心(平臺不可知的)構造函數中使用異步服務接口,並在我的HTML main()中傳入由GWT.create(MyService.class)(或至少包裝它)生成的GWT異步接口。我不知道這對非HTML版本有效。我可以直接從客戶端Java代碼使用GWT-RPC嗎?
  3. 使用其他形式的RPC。有什麼建議麼?
+1

不是一個完整的答案,但有一點: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

回答

12

對於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平臺:)。

+1

我繼續更新我的回答有點,因爲我已經成功地制定出了很多扭結的怎麼最近做到這一點... – hatboyzero 2012-02-03 19:45:10

+0

這聽起來像我可以做我的事與GWT RPC和採取這種做法,如果/當我想要支持非HTML輸出模式時。感謝您的詳細回覆! – 2012-02-18 22:39:39

+0

沒問題 - 很高興成爲服務:) – hatboyzero 2012-02-23 20:41:11

相關問題