应用层协议之WebSocket

devtools/2024/11/20 21:02:37/

WebSocket是一种在单个TCP连接上进行全双工通信的协议,它允许在客户端和服务器之间建立持久性的连接,使得数据可以在双方之间进行实时交换,而不需要客户端发起多个HTTP请求。WebSocket特别适用于需要实时通信、实时推送数据、实时同步编辑等场景。

一、WebSocket的特点

1. 双向通信

WebSocket实现了服务器与客户端之间的双向通信,即服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息。

2. 持久连接

一旦WebSocket连接建立,它将持续存在,直到被显式关闭。这种持久连接避免了HTTP请求/响应模式中的频繁握手和断开连接的开销。

3. 高效性

WebSocket使用较少的开销来维持连接,并且数据格式轻量,性能开销小,通信高效。

4. 兼容性和灵活性

WebSocket与HTTP协议有着良好的兼容性,默认端口也是80和443,并且握手阶段采用HTTP协议。此外,WebSocket可以发送文本和二进制数据,并且没有同源限制。

二、WebSocket与HTTP的区别

1. 连接性质

WebSocket是一种持久化的协议,连接不会在一次请求之后立即断开,而HTTP协议是基于请求-响应模式的,每次请求都需要客户端发起新的连接,并在收到响应后关闭。

2. 通信方式

WebSocket允许在客户端和服务器之间建立持久性的双向连接,客户端和服务器可以通过这个连接实时的交换数据。HTTP协议则是无状态的请求-响应协议,客户端向服务器发送请求,服务器处理请求并返回响应。

3. 数据格式

WebSocket协议支持传输文本或二进制数据,数据格式更加灵活,可以根据应用程序的需要自定义。HTTP协议通常用于传输文档、图像、视频等静态资源或者动态资源,数据格式通常是文本或者是二进制,但在每次请求和响应中都需要携带HTTP的头部信息。

4. 性能和效率

WebSocket通过在客户端和服务器之间建立持久连接,减少建立和关闭的开销,通信效率更高,延迟更低。HTTP协议在每次请求-响应周期中都需要消耗额外的资源来建立和关闭连接,通信效率相对较低。

三、WebSocket的握手过程

WebSocket连接的建立从一个HTTP请求开始,这个请求通常被称为“握手”请求。在请求中,客户端通过Upgrade和Connection头字段表示希望将协议从HTTP升级到WebSocket。服务器如果同意升级,会返回一个状态码为101 Switching Protocols的响应,表示协议升级成功。

四、WebSocket的常用应用场景

1. 实时聊天

WebSocket可以用于实现即时通讯功能,如在线聊天室、多人游戏等。

2. 实时数据更新

WebSocket可以用于实时地推送数据更新,如实时股票行情、实时天气预报等。

3. 协同编辑

WebSocket可以用于实现多人协同编辑功能,如在线文档协作、团队代码编辑等。

4. 实时监控

WebSocket可以用于实时监控系统,如监控设备的运行状态、实时监测交通流量等。

五、WebSocket的前端(Vue)实现

在Vue中使用WebSocket可以通过以下几个步骤来实现:

1. 创建WebSocket实例

const socket = new WebSocket('ws://your-websocket-server-url');

在这个示例中,用WebSocket构造函数创建了一个新的WebSocket实例,并传入了WebSocket服务器的URL。

2. 处理WebSocket事件

// 连接打开事件
socket.onopen = function(event) {console.log('WebSocket is open now.');
};// 消息接收事件
socket.onmessage = function(event) {console.log('WebSocket message received:', event);
};// 错误事件
socket.onerror = function(event) {console.error('WebSocket error observed:', event);
};// 连接关闭事件
socket.onclose = function(event) {console.log('WebSocket is closed now.');
};

3. 在Vue组件中使用WebSocket

<template><div><h1>WebSocket Example</h1><p>{{ message }}</p></div>
</template><script>
export default {data() {return {socket: null,message: ''};},created() {// 创建WebSocket实例this.socket = new WebSocket('ws://your-websocket-server-url');// 连接打开事件this.socket.onopen = (event) => {console.log('WebSocket is open now.');};// 消息接收事件this.socket.onmessage = (event) => {console.log('WebSocket message received:', event);this.message = event.data;};// 错误事件this.socket.onerror = (event) => {console.error('WebSocket error observed:', event);};// 连接关闭事件this.socket.onclose = (event) => {console.log('WebSocket is closed now.');};},beforeDestroy() {// 组件销毁前关闭WebSocket连接if (this.socket) {this.socket.close();}}
};
</script>

在这个示例中,我们在Vue组件的created生命周期钩子中创建了WebSocket实例,并添加了相应的事件处理程序。此外,我们还在组件销毁前的beforeDestroy钩子中关闭了WebSocket连接,以确保资源的正确释放。

六、WebSocket的后端(Java)实现

在Java后端使用WebSocket,首先需要添加WebSocket的依赖:

<!-- 引入websocket -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.1.8.RELEASE</version>
</dependency>

接下来,创建一个WebSocket配置类:

@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

然后,定义一个WebSocket服务端组件:

@Component
@ServerEndpoint("/ws/{clientId}")
public class WebSocketServer {private static Map<String, Session> sessionMap = new HashMap<>();@OnOpenpublic void opOpen(Session session, @PathParam("clientId") String clientId) {System.err.println("客户端:" + clientId + "建立连结");sessionMap.put(clientId, session);}@OnClosepublic void onClose(@PathParam("clientId") String clientId) {sessionMap.remove(clientId);}@OnMessagepublic void onMessage(String message, @PathParam("clientId") String clientId) {System.err.println("收到来自客户端" + clientId + "的消息:" + message);}public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}
}

在这个示例中,我们定义了一个WebSocket服务端组件,它包含连接打开、消息接收、连接关闭等事件的处理方法。同时,我们还提供了一个方法来向所有客户端发送消息。

七、WebSocket的心跳机制

为了确保WebSocket连接的活跃状态,通常会实现心跳机制。在客户端和服务器之间定期发送心跳消息,如果在一定时间内没有收到对方的心跳消息,则认为连接已经断开。

八、WebSocket的安全性

WebSocket连接需要特殊的安全设置以防止恶意攻击和数据泄漏。通常,可以使用SSL/TLS协议来加密WebSocket通信,以确保数据的安全性。

总结

WebSocket是一种强大的实时通信协议,它的双向通信和持久连接特性使得它在许多实时应用场景中发挥着重要作用。然而,在使用WebSocket时也需要注意其兼容性和安全性问题,并合理评估其对服务器资源的占用情况。通过前后端的协同工作,我们可以轻松实现实时通信功能,提升用户体验。


http://www.ppmy.cn/devtools/135581.html

相关文章

ObjectMapper mapper = new ObjectMapper()、使用 Jackson 将 JSON 转换为 Map!!!!!

ObjectMapper mapper new ObjectMapper(); 创建了一个 Jackson 的 ObjectMapper 实例&#xff0c;主要用于 JSON 和 Java 对象之间的转换。这是 Jackson 中的核心工具类。 mapper.readValue(json, Map.class); 使用 ObjectMapper 的 readValue 方法&#xff0c;将一个 JSON 字…

uniapp 设置form表单以及验证密码

事例&#xff1a; 代码&#xff1a; <template><view class"changePwd"><view class"login_form"><view class"title"><view>修改密码</view><view>您好&#xff0c;请在下方输入原密码和新密码进行…

HTTP CRLF注入攻击

HTTP CRLF注入攻击 大家好&#xff0c;今天我们来聊聊一个与网络安全相关的重要话题——CRLF注入&#xff08;CRLF Injection&#xff09;。了解这种安全漏洞有助于我们更好地保护我们的应用程序和用户数据。 什么是CRLF&#xff1f; CRLF代表Carriage Return (回车) 和 Line…

Dubbo源码解析-服务导出(四)

一、服务导出 当我们在某个接口的实现类上加上DubboService后&#xff0c;就表示定义了一个Dubbo服务&#xff0c;应用启动时Dubbo只要扫描到了DubboService&#xff0c;就会解析对应的类&#xff0c;得到服务相关的配置信息&#xff0c;比如&#xff1a; 1. 服务的类型&…

Vue3 动态获取 assets 文件夹图片

我真服了Vue3 这个老六了,一个简单图片src 赋值搞得那么复杂. //item.type 是我遍历类型的类型参数 <img alt"吐槽大会" :src"getAssetUrl(item.type)" /> 基于 Vue2 的Webpack 处理,还不错,可以用/ 这种绝对路径,可以接受,虽然多了个require很不爽…

C++设计模式:工厂方法模式

工厂方法模式是一种创建型设计模式&#xff0c;其核心是将对象的创建延迟到子类中&#xff0c;通过定义一个接口来创建对象&#xff0c;使得子类决定实例化哪一个类。它在需要扩展产品类型时特别有用&#xff0c;能够避免代码的重复和耦合。 工厂方法模式的核心概念 抽象产品&…

【MYSQL】什么是关系型数据库与非关系型数据库?

真正的让你快速理解什么是关系型数据库与非关系型数据库~ 主要是以查询语句&#xff0c;存储结构&#xff0c;拓展 性上的区别。 关系型数据库&#xff08;最经典就是mysql&#xff0c;oracle&#xff09;&#xff1a;它是支持SQL语言&#xff0c;并且关系型数据库大部分都支持…

强化学习数学原理学习(四)

前言 今天是时序差分学习 正文 首先,明确一点,时序差分也是无模型的情况下的强化学习方法,TD学习是蒙特卡洛思想和动态编程&#xff08;DP&#xff09;思想的结合。最基础的时序差分学习估计状态值&#xff0c;而后续提出的Sarsa和Q-learning方法则直接对动作值进行估计。 …