2017-02-09 4 views
0

J'ai un webservice RESTful que j'utilise pour un serveur sur NetBeans. Ce webservice devrait recevoir beaucoup de demandes de clients (jeu multijoueur). Je ne suis pas encore familiarisé avec ce sujet, mais si je comprends bien, tous les appels des clients à mon service web sont sécurisés, car chaque connexion au service Web est sur un thread différent (toutes mes variables sont à l'intérieur du méthodes webservice) est-ce vrai?Puis-je utiliser wait() dans un webservice RESTful?

Et cela m'amène à ma question: Puis-je utiliser wait(); dans une méthode de service Web? disons que j'attends deux connexions client, donc la seconde connexion va utiliser notifyAll(); Mais puisque le webservice n'est pas vraiment un thread je ne sais pas s'il est possible d'utiliser ces méthodes là-bas? Que devrais-je utiliser à la place ??

Ceci est mon webservice:

@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); 
    } 
} 

Client:

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

Avant multithreading. 'if (Utility.count = 1)' devrait être 'if (Utility.count == 1)', le premier assignant 1 à compter. Deuxième point, le second 'if' devrait être un' else if' –

+0

Merci! Oui je l'ai écrit comme une idée, mon problème est le wait() et notify() dans un webservice – SHAI

+0

Oubliez le code, que voulez-vous réaliser concrètement? –

Répondre

1

Vous pouvez toujours utiliser wait() et notify() car cela affecte le thread sur lequel s'exécute le code. Que vous utilisiez ou non dépend de la situation.

Si vous voulez une file d'attente de joueurs utilisent alors une file d'attente :)

Un petit exemple, je en cloque ...

@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

Hey merci beaucoup pour votre commentaire! J'ai essayé de le faire, le problème est que la connexion est perdue après wait() ... Mon client (1er joueur) se connecte au serveur, le serveur fait "wait() - ce qui fait que Mon client abandonne la connexion (" capture").Le 2nd Client notifiera() - comme dans votre code ce qui fera que - le premier joueur continuera à fonctionner sur le serveur - mais le client ne le sait pas puisque la connexion a été perdue à cause de wait(); – SHAI

+0

J'ai ajouté mon client de base – SHAI

+0

Peu étonnant puisque vous avez défini votre délai d'attente à 5 secondes :) Pouvez-vous simplement augmenter vos délais d'attente? Si ce n'est pas le cas, et que vous voulez suivre cette approche, vous devrez utiliser l'interrogation - par exemple. Continuez à demander un adversaire jusqu'à ce qu'il devienne disponible. – TedTrippin

1

Oui. Toutes les variables locales dans les méthodes sont thread-safe. Les variables de classe peuvent être thread-safe ou ne pas l'être. C'est à toi de decider. Si le contrôleur de repos a une portée singleton (généralement par défaut), cela signifie que les champs de classe sont partagés entre toutes les requêtes. Donc, techniquement, vous pouvez utiliser un objet verrouillé partagé pour synchroniser dessus. Essaye de le faire. Mais il vaut mieux le faire en mode asynchrone. Voir la technique Reverse Ajax Comet avec une longue interrogation dans l'article this.

Vous pouvez également utiliser Reverse Ajax with Websockets et renvoyer le 'Transfert reçu' au client sans aucune inactivité.

+0

Merci, j'essaie toujours de le comprendre. Je vais devoir utiliser webservice parce que c'est un projet pour l'école – SHAI