2017-02-09 15 views
0

NetBeans上のサーバーに使用するRESTful Webサービスがあります。 このウェブサービスは、クライアントから多くのリクエストを受けるべきです(マルチプレイヤーゲーム)。RESTfulなWebサービスでwait()を使用できますか?

私はまだこのトピックに慣れていませんが、クライアントからWebサービスへのすべての呼び出しがスレッドセーフであることを理解していれば、Webサービスへのすべての接続が別のスレッドにあります。 Webサービスメソッド)これは本当ですか?

これは私の質問に私をもたらします: wait();をウェブサービスの方法で使用できますか?私は2つのクライアント接続を待っているとしましょう、2番目の接続が使用されます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)'でなければなりません。 2番目のポイント、2番目の 'if'は' else if'です。 –

+0

ありがとう!はい私はアイデアとしてそれを書いた、私の問題は、webserviceで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()の後に失われていることです。クライアント(1番目のプレーヤー)がサーバに接続し、サーバは "wait()キャッチ")。第2のクライアントはあなたのコードのようにnotify()を実行します。サーバ上で実行を続けるためには第1のプレーヤーが行いますが、クライアント側はwait()のために接続が失われたのでそれについて知りません。 – SHAI

+0

私の基本クライアントを追加しました – SHAI

+0

あなたのタイムアウトを5秒に設定して以来驚くことはありません:)タイムアウトを増やせますか?もしそうでなければ、このアプローチに固執したいのですが、ポーリングを使う必要があります。相手が利用可能になるまで相手方に依頼し続ける。 – TedTrippin

1

はい。メソッド内のすべてのローカル変数はスレッドセーフです。クラスフィールドの変数はスレッドセーフであるか、スレッドセーフではない可能性があります。それはあなた次第です。残りのコントローラにシングルトンスコープがある場合(通常はデフォルトで)、クラスフィールドはすべてのリクエストで共有されます。

技術的には、共有ロックオブジェクトを使用して同期させることができます。それをやってみてください。しかし、非同期モードで行う方が良いでしょう。長いポーリングによるAjax Cometの逆テクニックをthisでご覧ください。

また、Reverse Ajax with Websocketsを使用して、「転送が受信されました」をアイドル状態のままクライアントに送り返すことができます。

+0

ありがとう、私はまだそれを理解しようとしています。私はそれが学校のプロジェクトのためwebserviceを使用する必要があります – SHAI

関連する問題