2017-02-09 45 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

相关问题