2017-02-09 77 views
0

我有一個REST風格的web服務,我使用NetBeans上的服務器。 這個web服務應該從客戶端(多人遊戲)獲得很多請求。我可以在RESTful Web服務中使用wait()嗎?

我仍然對這個主題不熟悉,但如果我理解它是正確的 - 從客戶端到我的webservice的每個調用都是線程安全的 - 因爲與web服務的每個連接都在不同的線程上(所有變量都在webservice方法)是真的嗎?

這使我想到我的問題: 我可以在webservice方法中使用wait();嗎?假設我正在等待兩個客戶端連接,所以第二個連接將使用notifyAll(); 但由於web服務並不是一個真正的線程,我不知道是否有可能在那裏使用這些方法?我應該用什麼來代替?

這是我的web服務:

@Path("/w") 
public class JSONRESTService { 
    String returned; 

    @POST 
    @Consumes("application/json") 
    @Path("/JSONService") 
    public String JSONREST(InputStream incomingData) { 
     StringBuilder JSONBuilder = new StringBuilder(); 
     try { 
      BufferedReader in = new BufferedReader(new InputStreamReader(incomingData)); 
      String line = null; 
      while ((line = in.readLine()) != null) { 
       JSONBuilder.append(line); 
      } 

      returned = "transfer was completed"; 

      // This is what I'm trying to add but I know that I can't: 

      // count is a static variable, every new connection will increase this value  

      // only one player is connected 
      if (Utility.count == 1)  
       wait(); //wait for a 2nd player to connect to this webservice 

      // 2nd player is connected to this webservice 
      if (Utility.count == 2) 
       notifyAll();   // notify the 1st player 

     } catch (Exception e) { 
      System.out.println ("Error Parsing: - "); 
      returned ="error"; 
     } 
     System.out.println ("Data Received: " + JSONBuilder.toString()); 
     return (returned); 
    } 
} 

客戶:

JSONObject jsonObject = new JSONObject("string"); 

// Step2: Now pass JSON File Data to REST Service 
try { 
    URL url = new URL("http://localhost:8080/w/JSONService"); 
    URLConnection connection = url.openConnection(); 
    connection.setDoOutput(true); 
    connection.setRequestProperty("Content-Type", "application/json"); 
    connection.setConnectTimeout(5000); 
    connection.setReadTimeout(5000); 
    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream()); 
    out.write(jsonObject.toString()); 
    out.close(); 

    //string answer from server: 
    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
    StringBuffer sb = new StringBuffer(""); 
     String line=""; 
     while ((line = in.readLine()) != null) { 
      sb.append(line); 
      System.out.println("\n"+line); 
    in.close(); 
} catch (Exception e) { 
    System.out.println("\nError while calling JSON REST Service"); 
    System.out.println(e); 
} 

br.close(); 
} catch (Exception e) { 
e.printStackTrace(); 
} } }` 
+0

多線程之前。 'if(Utility.count = 1)'應該是'if(Utility.count == 1)',第一個分配1來計數。第二點,第二個'if'應該是'else if' –

+0

謝謝!是的,我寫它作爲一個想法,我的問題是web服務中的wait()和notify() – SHAI

+0

忘記代碼,你想具體實現什麼? –

回答

1

您可以隨時使用wait()notify(),因爲它會影響運行代碼的線程。是否應該使用它取決於情況。

如果你想要的球員隊列,然後使用一個隊列:)

一個小例子,我懷孕了......

@Path("/w") 
public class JSONRESTService { 

    private static BlockingQueue<Player> queue = new ArrayBlockingQueue<>(999); 

    @POST 
    @Consumes("application/json") 
    @Path("/JSONService") 
    public String JSONREST(InputStream incomingData) {  


     Player thisPlayer = ...; // Get player from session or something 

     System.out.println (thisPlayer.getName() + " starting..."); 

     try { 

      if (queue.isEmpty()) { 
       System.out.println ("waiting for an opponent"); 
       queue.add(thisPlayer); 
       synchronized (thisPlayer) { 
        thisPlayer.wait(); 
       } 
      } else { 
       System.out.println ("get next in queue"); 
       Player opponent = queue.take(); 
       opponent.setOpponent(thisPlayer); 
       thisPlayer.setOpponent(opponent); 
       synchronized (opponent) { 
        opponent.notify(); 
       } 
      } 

      System.out.println (thisPlayer.getName() + " playing " + thisPlayer.getOpponent().getName()); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    static class Player { 

     private String name; 
     private Player opponent; 

     Player (String name) { 
      this.name = name; 
     } 

     public String getName() { 
      return name; 
     } 

     public Player getOpponent() { 
      return opponent; 
     } 

     public void setOpponent(Player opponent) { 
      this.opponent = opponent; 
     } 
    } 
} 
+0

嘿,非常感謝您的評論!我試圖做到這一點,問題是,等待()後連接丟失()...我的客戶端(第一個播放器)連接到服務器,服務器「wait() - 什麼使我的客戶端放棄連接(」抓住」)。第二個客戶端會執行notify() - 就像在你的代碼中一樣 - 第一個播放器繼續在服務器上運行 - 但客戶端不知道它,因爲連接因爲wait(); – SHAI

+0

我添加了我的基本客戶端 – SHAI

+0

因爲您已將您的超時設置爲5秒,所以非常令人驚訝:)您可以增加超時嗎?如果沒有,並且你想堅持這種方法,你將需要使用輪詢 - 例如。不斷請求對手,直到有人可用。 – TedTrippin

1

是。方法內的所有局部變量都是線程安全的。類字段變量可能是線程安全的或可能不是。它是由你決定。如果rest控制器具有單例作用域(通常默認情況下它是),這意味着所有請求之間共享類字段。

所以,從技術上講,你可以使用一些共享鎖對象來同步它。試着去做。但最好在異步模式下進行。在this文章中查看反向Ajax Comet技術和長查詢。

或者,您也可以使用Reverse Ajax with Websockets並將「已收到轉讓」發送回客戶端,無任何空閒。

+0

謝謝,我仍然試圖找出它。我將不得不使用webservice,因爲這是一個學校項目 – SHAI

相關問題