3

我正在做一个家庭作业项目,该项目应该通过 HttpServlet 在 2 个客户端之间实现棋盘游戏。我有几个问题:

1)我读到HttpServlets必须是无状态的,但是,为了游戏,我必须保留很多状态(轮到谁,棋盘的状态等)。我必须将其保留在客户中吗?HttpServlet 是否确实必须是无状态的,即没有跟踪状态的字段?

2) 我知道客户端会通过 doGet/doPost 方法与 servlet 对话,但是 servlet 如何与客户端对话(例如,如果玩家 1 刚刚移动并将其发送到 servlet,则 servlet 必须告诉客户 2 移动是什么)。

谢谢

另外,如果您能指出一个有用的、简单的在线类似代码示例,我将不胜感激

4

4 回答 4

3
  1. HTTP 协议是无状态的,因此是 HttpServlet。您可以使用 servlet api 在服务器端维护会话状态。阅读会话管理教程

  2. 有几种技术,例如 H TML auto-refreshCometHTML 5 的 WebSocket等技术

于 2012-08-16T02:18:15.713 回答
2

Servlet 需要能够处理多个请求——它们不需要是无状态的,但它们必须管理该状态以避免典型的多线程问题。显然,如果您有两个用户需要访问同一个世界,您需要一种机制。假设服务器将帮助跟踪游戏状态,如果没有其他原因,只是为了避免作弊或恶意客户端。

有多种选择;客户端可以轮询移动更新,您可以使用长轮询等。

于 2012-08-16T02:14:50.880 回答
1

其他人已经涵盖了#1。

我只会对#2 提出建议。另一种选择是快速了解 AJAX(异步 Javascript 和 XML)。您可以触发“幕后”HTTP 请求并调整页面,而无需用户刷新页面。客户端可以加载 HTML 页面,该页面可以包含每隔几秒钟与服务器检查一次更新并刷新其板的 javascript。

这是一个小例子。此外,如果您不想担心特定于浏览器的 javascript,您可以使用 jQuery。它具有非常用户友好的 api,用于触发 ajax 请求,并处理特定于浏览器的内容。

编辑

好的,对于#1 - 您的 servlet 将用于服务所有请求,可能是并行的。你不能将你的游戏板直接放在 servlet b/c 中,那么你可能有 20 个人试图编辑同一个游戏。

public class GameServlet extends HttpServlet {
   private GameBoard board; // everyone would share the same board!

您有几个选择,您可以将板存储在用户访问的某个集合中。您可能还想看看 HttpSession。HttpSession 是服务器端内存的一部分,servlet 将为您跟踪它,您可以跨请求访问它。

public void doGet(HttpServletRequest req, HttpServletResponse resp) {

  HttpSession session = req.getSession();
  session.setAttribute("board", new GameBoard());  // this way each user will have their own game board

  // and you can retrieve it in another HTTP request
  GameBoard board = session.getAttribute("board");
}

使用 HttpSession 对您来说可能有点棘手,因为板更新实际上必须更新两个用户的板。您可能只喜欢 servlet 上由用户索引的集合成员。希望这足以让你开始。

于 2012-08-16T02:25:41.313 回答
0

HTTP 作为一种协议是无状态的(正如人们所提到的)。但是,一小部分 http 在服务器和客户端之间来回传递“Cookies”。这些 cookie 是一个单独的 RFC (http://www.ietf.org/rfc/rfc2109.txt),由 HTTP 客户端(即浏览器)进行交互。在 HTTP 方面,cookie 只是另一个头字段,但它们对浏览器具有特殊的意义。

将这些 cookie 用于基于 servlet 的程序将会话 ID 传递回客户端浏览器的一种用途。当客户端发送后续请求时,相同的 cookie 会自动发送回发出它的服务器。服务器识别那个并且那个标识符用户会话。这对程序员来说大多是透明的。

通常,tomcat(或其他一些容器)会为您处理这个,您所要做的就是询问会话的 servlet 请求:

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    // the parameter determines if session can be created if one does not exist for the client
    HttpSession session = req.getSession(true); 

    session.setAttribute("attName", attValue);
}

您可以使用会话来存储/检索属性。至于常见的游戏状态,很可能应该存储在其他地方(某种游戏管理器对象),但是您可以在用户的​​会话中存储用户当前的游戏 id,这将允许 servlet 为用户找到合适的游戏. 当用户移动时,游戏状态会通过指示这一点的 http 请求更新。两个用户都必须定期发出 http 请求来询问游戏的当前状态、最近的动作等......

于 2012-08-16T02:51:41.093 回答