1.概述
大家好我是码农小胖哥,在本文中,我们将介绍客户端 - 服务器通信的基础知识,并通过今天提供的两种流行选项进行探索。我们将看到作为新进入者的WebSocket如何与更受欢迎的RESTful HTTP选择相媲美。
2.网络通信基础知识
在深入探讨不同选项及其优缺点的细节之前,让我们快速刷新网络通信的前景。这将有助于将事情放在透视中并更好地理解这一点。
根据开放系统互联通信模型(OSI)可以最好地理解网络通信。
OSI划分为七层抽象:
在这个模型的顶部是Application层,这是我们在本教程中感兴趣的。但是,在我们比较WebSocket和RESTful HTTP时,我们将讨论前四个层中的一些方面。
应用程序层最接近最终用户,负责与参与通信的应用程序连接。在这一层中使用了几种流行的协议,如FTP,SMTP,SNMP,HTTP和WebSocket。
3.描述WebSocket和RESTful HTTP
虽然可以在任意数量的系统之间进行通信,但我们对客户端 - 服务器通信特别感兴趣。更具体地说,我们将专注于Web浏览器和Web服务器之间的通信。这是我们用来比较WebSocket和RESTful HTTP的框架。
但在我们继续前进之前,为什么不快速了解它们是什么呢!
3.1 WebSockets
正如定义所述,WebSocket是一种通信协议,它通过持久TCP连接进行双向,全双工通信。现在,我们将继续详细了解本声明的每个部分。
WebSocket 在2011年由IETF标准化为RFC 6455的通信协议。如今大多数现代Web浏览器都支持WebSocket协议。
3.2 RESTful HTTP
虽然我们都知道HTTP,因为它在互联网上无处不在,但它也是一种应用层通信协议。HTTP是一种基于请求 - 响应的协议,我们将在本教程后面再次理解这一点。
REST(Representational State Transfer)是一种体系结构样式,它在HTTP上设置一组约束来创建Web服务。
4. WebSocket子协议
虽然WebSocket定义了客户端和服务器之间双向通信的协议,但它不会对要交换的消息施加任何条件。作为子协议谈判的一部分,通信方可以同意这一点。
为非平凡的应用程序开发子协议是不方便的。幸运的是,有许多流行的子协议,如STOMP可供使用。STOMP代表简单文本导向的消息传递协议,适用于WebSocket。Spring Boot拥有对STOMP的一流支持,我们将在本教程中使用它。
5. Spring Boot中的快速设置
没有比看到一个有效的例子更好的了。因此,我们将在WebSocket和RESTful HTTP中构建简单的用例,以进一步探索它们,然后进行比较。让我们为两者创建一个简单的服务器和客户端组件。
我们将使用JavaScript创建一个简单的客户端,它将发送一个名称。而且,我们将使用Java创建一个服务器,它将以问候语进行响应。
5.1。的WebSocket
要在Spring Boot中使用WebSocket,我们需要加入webSocket的功能组件:
org.springframework.boot
spring-boot-starter-websocket
我们现在将配置STOMP端点:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/topic");
}
}
让我们快速定义一个简单的WebSocket服务器,它接受一个名字并用问候语回复:
@Controller
public class WebSocketController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(Message message) throws Exception {
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + “!”);
}
}
最后,让我们构建客户端以与此WebSocket服务器进行通信。在我们强调浏览器到服务器的通信时,让我们用JavaScript创建一个客户端:
var stompClient=null;
function connect() {
stompClient=Stomp.client(‘ws://localhost:8080/ws’);
stompClient.connect({}, function (frame) {
stompClient.subscribe(’/topic/greetings’, function (response) {
showGreeting(JSON.parse(response.body).content);
});
});
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({‘name’: $("#name").val()}));
}
function showGreeting(message) {
$("#greetings").append("" + message + “”);
}
这完成了我们WebSocket服务器和客户端的减肥方法。代码存储库中有一个HTML页面,它提供了一个简单的用户界面来进行交互。
虽然这只是表面上的问题,但是使用Spring的WebSocket可以用来构建复杂的聊天客户端等等。
5.2。RESTful HTTP
我们现在将为RESTful服务进行类似的设置。我们的简单Web服务将接受带有名称的GET请求并以问候语进行响应。
我们这次使用Spring Boot的Web组件:
org.springframework.boot
spring-boot-starter-web
现在,我们将利用Spring中提供的强大注释支持来定义REST端点:
@RestController
@RequestMapping(path="/rest")
public class RestAPIController {
@GetMapping(path="/{name}", produces=“application/json”)
public String getGreeting(@PathVariable(“name”) String name)
{
return "{“greeting” : “Hello, " + name + “!”}”;
}
}
最后,让我们用JavaScript创建一个客户端:
var request=new XMLHttpRequest()
function sendName() {
request.open(‘GET’, ‘localhost:8080/rest/’+$("#name").val(), true)
request.onload=function () {
var data=JSON.parse(this.response)
showGreeting(data.greeting)
}
request.send()
}
function showGreeting(message) {
$("#greetings").append("" + message + “”);
}
这就是它!同样,代码存储库中有一个HTML页面,用于处理用户界面。
虽然其简洁性很深,但定义生产级REST API可以完成更广泛的任务!
6. WebSocket和RESTful HTTP的比较
在创建了WebSocket和RESTful HTTP的最小但有效的示例后,我们现在已经准备好了解它们如何相互对抗。我们将在下一小节中针对几个标准对此进行检查。
值得注意的是,虽然我们可以直接比较HTTP和WebSocket,因为它们都是应用程序层协议,但将REST与WebSocket进行比较并不自然。正如我们之前看到的,REST是一种利用HTTP进行通信的架构风格。REST并不是一个规范,一个协议,只是对http请求状态的表述。
因此,我们与WebSocket的比较主要是关于HTTP中的功能或缺乏功能。
6.1 网址方案
URL 定义Web资源的唯一位置和检索它的机制。在客户端 - 服务器通信中,我们通常希望通过其关联的URL获取静态或动态资源。
我们都熟悉HTTP URL方案:
localhost:8080/rest
WebSocket URL方案也没有太大的不同:
ws://localhost:8080/ws
一开始,唯一的区别似乎是冒号之前的字符,但它抽象了很多,发生在引擎盖下。让我们进一步探讨。
6.2。握手
握手 是指在通信方之间协商通信协议的自动方式。HTTP是一种无状态协议,适用于请求 - 响应机制。在每个HTTP请求上,通过套接字与服务器建立TCP连接。
然后客户端等待,直到服务器响应资源或错误。来自客户端的下一个请求重复所有内容,就好像之前的请求从未发生过一样:
与HTTP相比,WebSocket的工作方式非常不同,并且在实际通信之前以握手开始。
让我们看看WebSocket握手的组成部分:
对于WebSocket,客户端在HTTP中启动协议握手请求,然后等待服务器响应接受从HTTP升级到WebSocket。
当然,由于协议握手是通过HTTP发生的,因此它遵循上图中的序列。但是一旦建立连接,就从客户端和服务器上切换到WebSocket进行进一步的通信。
6.3 连接
正如我们在上一小节中看到的,WebSocket和HTTP之间的一个明显区别是WebSocket在持久TCP连接上工作,而HTTP为每个请求创建一个新的TCP连接。
现在显然为每个请求创建新的TCP连接并不是非常高效,HTTP也没有意识到这一点。实际上,作为HTTP / 1.1的一部分,引入了持久连接以缓解HTTP的这一缺点。
尽管如此,WebSocket的设计初衷是为了使用持久的TCP连接。
6.4 通讯
WebSocket over HTTP的好处是一个特定的场景,这个场景源于客户端服务器可以用旧的HTTP无法实现的方式进行通信。
例如,在HTTP中,通常客户端发送该请求,然后服务器响应请求的数据。服务器没有通用的方式来自己与客户端通信。当然,已经设计出模式和解决方案来规避服务器发送事件(SSE),但这些并不完全自然。
使用WebSocket,处理持久性TCP通信,服务器和客户端都可以相互独立地发送数据,事实上,对于许多通信方来说!这被称为双向通信。
WebSocket通信的另一个有趣特性是它是全双工的。现在虽然这个词可能听起来很深奥; 它只是意味着服务器和客户端都可以同时发送数据。将此与HTTP中发生的情况进行比较,其中服务器必须等待它才能完全接收请求,然后才能响应数据。
虽然双向和全双工通信的好处可能不会立即显现出来。我们将看到一些用户解锁一些真正的力量的用例。
6.5。安全
最后但同样重要的是,HTTP和WebSocket都利用了TLS的优势来提高安全性。虽然HTTP提供HTTPS作为使用该网页的网址方案的一部分,已经的WebSocket WSS为同样的效果的URL方案的一部分。
因此,前一小节中的URL的安全版本应如下所示:
localhost:443/rest
wss://localhost:443/ws
保护RESTful服务或WebSocket通信是一个非常深入的主题,这里不能涵盖。现在,我们只是说两者在这方面得到了充分的支持。
7.使用场景有哪些?
现在,我们已经看到足够的基于HTTP的RESTful服务和基于WebSocket的简单通信,以形成我们对它们的看法。但是我们应该在哪里使用什么?
重要的是要记住,虽然WebSocket出现了HTTP中的缺点,但实际上并不是HTTP的替代品。所以他们都有自己的位置和用途。让我们快速了解我们如何做出决定。
对于服务器需要偶尔进行通信的大部分情况,例如获取员工的记录,使用REST服务而不是HTTPS仍然是明智的。但对于较新的客户端应用程序,例如需要从服务器进行实时更新的股票价格应用程序,利用WebSocket非常方便。
概括来讲,WebSocket更适用于基于推送和实时通信更恰当地定义需求的情况。此外,WebSocket适用于需要同时将消息推送到多个客户端的情况。在这些情况下,通过RESTful服务进行客户端和服务器通信会发现很难。因为http是客户端到服务器的请求-应答处理。
然而,需要从需求中提取通过HTTP使用WebSocket和RESTful服务。就像没有银弹一样,我们不能指望选择一个来解决每一个问题。因此,我们必须运用智慧和知识来设计有效的沟通模式。
共同学习,写下你的评论
评论加载中...
作者其他优质文章