2011-02-17 75 views
3

我一直在問一些關於如何在我的客戶端服務器環境中使用命令協議的問題。然而,經過一番實驗,我得出的結論是它不適合我。它不是爲這種情況設計的。因此我處於一個鬆散的結局。Java Socket RPC協議

我已經實現了一種RPC機制,在此之前我有一個名爲「Operation」的類。我還有一個名爲「Action」的枚舉,其中包含可以在服務器上調用的操作的名稱。

現在,在我的舊項目中,客戶端每次想要在服務器上調用一個操作時,它都會創建一個「Operation」實例,並使用「Action」枚舉中的值設置操作變量。例如

Operation serverOpToInvoke = new Operation();
serverOpToInvoke.setAction(Action.CREATE_TIME_TABLE);
serverOpToInvoke.setParameters(Map params);
ServerReply reply = NetworkManager.sendOperation(serverOpToInvoke);
...

在服務器端,我不得不執行確定通過用「的if/else」語句的負荷檢查「操作」枚舉值來調用該方法的可怕任務。當找到一場比賽時,我會調用適當的方法。

與此問題是,它是凌亂的,很難維護,最終是不好的設計。

我的問題是這樣的 - 是否有某種模式,我可以按照java中的TCP套接字實現一個漂亮,清潔和可維護的rpc機制?由於客戶端(android)不支持RMI,因此RMI對我來說是不可行的。在這個階段我已經耗盡了所有的途徑。唯一的其他選擇可能是REST服務。任何建議都會非常有幫助。

非常感謝您 問候

回答

8

可能最簡單的解決方案是鬆散地遵循RMI的路徑。

您有一個接口和一個實現開出:

interface FooService { 
    Bar doThis(String param); 
    String doThat(Bar param); 
} 

class FooServiceImpl implements FooService { 
    ... 
} 

您部署的接口兩側和實施僅在服務器端。

然後要獲取客戶端對象,請創建一個動態代理。其調用處理程序除了序列化服務類名稱,方法名稱和參數並將其發送到服務器(最初可以使用ObjectOutputStream,但可以使用替代序列化技術,例如XStream)之外,不會執行任何其他操作。

服務器偵聽器接受這個請求並使用反射來執行它,然後發回響應。

這個實現相當簡單,雙方都是透明的,唯一的主要問題是你的服務實際上是單身。

如果需要,我可以包含一些更多的實現細節,但如果我必須實現類似的東西,那麼我會遵循這個總體思路。儘管如此,我可能會多搜索一下已有的解決方案,比如webservices或類似的東西。

更新:這是普通的(本地)調用處理程序會做的。

class MyHandler implements InvocationHandler { 

    private Object serviceObject; 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) 
      throws Throwable { 
     return method.invoke(serviceObject, args); 
    } 
} 

其中serviceObject是您的服務實現對象包裝到處理程序中。

這是你必須減少一半,而不是調用方法,您需要發送以下服務器:

  1. 接口的全名(或其他一些價值唯一標識服務接口)
  2. 方法的名稱。
  3. 該方法需要的參數類型的名稱。
  4. args array。

服務器端必須:

  1. 查找該接口的實現(最簡單的方法是有某種地圖,其中鍵是接口名稱和值執行單個實例)
  2. 找到方法,使用Class.getMethod(name, paramTypes);
  3. 通過調用method.invoke(serviceObject, args);執行該方法並將返回值發回。
+0

嗨biziclop,當你提到使用反射執行命令的服務器,你能詳細解釋一下嗎?你昨天回答了一個關於我的命令模式的帖子,從那以後,我讀到了強大的動態代理。我很感謝代碼。我對整體概念更感興趣。非常感謝您的幫助 – Joeblackdev 2011-02-17 19:45:31

+1

@Joeblackdev更新了我的答案,希望它有所幫助。 – biziclop 2011-02-17 20:05:19

0

RMI是要走的路。

Java RMI的是Java應用程序 程序編程接口,其執行 面向對象的等效的 遠程過程調用(RPC)。

+0

嗨Klark,我不能在這裏使用RMI。客戶端平臺(Android)不利於使用RMI。 – Joeblackdev 2011-02-17 19:42:47

2

你應該看看協議緩衝區從谷歌:http://code.google.com/p/protobuf/

這個庫定義了一個IDL用於產生等,其可以被寫入並從流/字節數組/等讀取的類結構體。他們還使用定義的消息定義RPC機制。

我用這個庫來解決類似的問題,它工作得很好。