我们需要设计一个服务器,为多个客户端提供网页,同时还为这些客户端查询远程数据库。该项目的一个要求是整个系统必须符合REST架构风格。我们需要使用Java作为编程语言,但在我们设计时会出现很多问题。
我们希望有一个可以获得连接的主线程,如下例所示:
// System.out.println("Starting a new web server using port " + port)
try {
ServerSocket reciever = new ServerSocket(port);
while (true) {
try {
Socket s = reciever.accept();
Client c = new Client(s);
} catch (IOException e) {
System.err.println("New item creation failed.");
IOUtil.close(reciever);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
System.err.println("ServerSocket problem.");
}
然后,每个连接将被创建为一个新线程(代码中的Client对象),它将负责读取一个请求。如果请求是GET,则线程将资源提供给客户端。如果是POST,那么它会将请求添加到缓冲区,让另一个线程处理对数据库的查询以及回复客户端的答案。在处理此唯一请求后,线程关闭套接字并终止。
套接字的使用是否违反了REST原则?为了尊重REST架构,我们是否需要在每条HTTP消息之后销毁每个Client对象(线程和套接字)?还有另一种不使用套接字的客户端 - 服务器通信方式吗?
答案 0 :(得分:2)
好吧,我觉得你把一大堆垃圾搞得一团糟。
首先,允许数据从A到B的低级IP套接字和使用HTTP来引导从客户端到服务器的“websockets”之间存在差异,这些连接可以保持打开以进行TWO WAY通信。
根据您的要求,您只需要一个“标准”JEE容器。使用类似JAX-RS之类的东西,您可以对@PATH('/MyResource/Cars/')
等函数应用一些基本注释,并为该路径调用该函数。
使用容器可以让你摆脱那些无聊的样板垃圾。无需手动设置线程来监听,并产生其他线程来处理请求。
使用IP套接字(间接)是REST的任务; REST必须(根据Fielding,但严格来说它是协议不可知)通过HTTP,因此通过TCP / IP套接字(尽管显然你可以通过任何其他传输协议执行HTTP)。然而,Websockets使用HTTP在客户端和服务器之间形成持久的有状态连接,这与REST基本相反。基本的HTTP会(你会通过容器为你做这件事)完全打开并关闭每个隔离请求的连接,但实际上HTTP(以及REST)将允许低级连接(TCP连接是缓慢开始)为一系列请求维护。此功能旨在用于加载HTML页面的范围,以及一个TCP连接中的所有资源,但是通过许多HTTP请求。
答案 1 :(得分:1)
套接字通过TCP / IP移动字节。这是一个较低级别的协议,您不必担心这一点。你关心更高的协议(在这种情况下是HTTP)。
每次请求后,套接字都会在HTTP中关闭,所以你的想法听起来很合理。虽然我不确定为什么要为POST请求创建单独的线程。我假设您的Client
实现已经在自己的线程中运行(如果没有,那么您的服务器效率不高)。