【WebSocket探秘】解锁 WebSocket:开启实时交互新境界
前言
🌟🌟本期讲解关于websocket的相关知识介绍~~~
🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客
🔥 你的点赞就是小编不断更新的最大动力
🎆那么废话不多说直接开整吧~~
目录
📚️1.WebSocket介绍
🚀1.1传统服务器
1.1.1适应情况
🚀1.2消息推送实现
1.2.1轮询机制实现
🚀1.3WebSocket报文格式
🚀1.4WebSocket握手过程
📚️2.WebSocket编码
🚀2.1后端服务器
🚀2.2前端客户端
🚀2.3运行日志
📚️3.总结
📚️1.WebSocket介绍
🚀1.1传统服务器
在传统服务器开发中,一问一答模式是一种常见且基础的交互方式,主要基于 HTTP 协议进行通信。这种模式下,客户端和服务器之间的交互流程较为清晰,每次交互都包含一个明确的请求和对应的响应。
客户端发起请求时,会将包含特定信息的请求报文发送给服务器。这个请求报文里涵盖了请求方法(如 GET、POST 等)、请求头(包含客户端的一些信息,如浏览器类型、缓存策略等)以及请求体(若有需要传输的数据,如表单数据、JSON 格式数据等
1.1.1适应情况
这种一问一答的传统服务器开发模式适用于很多对实时性要求不高的场景。
比如普通的网页浏览,用户浏览不同页面时,虽然每次请求都有一定延迟,但对用户体验影响不大。
缺点:
然而,在实时性要求较高的场景下,如在线聊天、实时数据监控、股票行情展示等,一问一答模式就显得力不从心。因为它无法及时地将服务器端的数据变化推送给客户端
例如:
在网上联机实现棋类对战的时候,需要实时更新棋盘情况,如下所示:
此时就需要服务器主动发送信息给客户端,这个过程叫“消息推送”,那么此时http协议就比较难完成了,但是也是可以实现的;
🚀1.2消息推送实现
我们在上述说到,http可以实现,那么如何进行实现呢?其实存在HTTP实现的过程我们叫“轮询机制”,那么轮询机制的实现过程是如何的呢?
1.2.1轮询机制实现
由于HTTP是一问一答的格式,所以玩家2要不断的,按照一定间隔时间去访问服务器,来获得服务器响应,若没有响应说明玩家一还没有落子,响应了,说明玩家1已经落子,从而获取信息;
如下图所示:
但是像这种不断的访问会有致命的缺陷:
轮询时间间隔过大:客户端2不能及时获取得到信息的更新情况
轮询时间间隔过小:浪费机器资源,带宽(因为不断发送意义不大的请求)
所以websocket的诞生就很好解决了这个问题,他就可及时,主动的发送更新的信息给客户端,他就是实现“消息推送”的主要的方式;
🚀1.3WebSocket报文格式
这里小编只介绍几个比较重要的:
FIN:结束报文,这和TCP哪里挥手意思差不多,如果为1,则该消息为消息尾部;如果为0,则还有后续数据包;
RSV:保留位,用于扩展定义;
opcode字段:描述当前WebSocket报文是什么类型的(表示文本帧,二进制帧,或者ping帧,pong帧,大致就是心跳包机制,判断对方是否正常工作)
Payload length:当前数据报携带的数据载荷长度,字段本身就是变长的,所以WebSocket数据报承载的载荷长度是很长的;
Mask- key:保证数据安全
Payload data:实际报文传输的数据载荷
🚀1.4WebSocket握手过程
网页尝试和服务器建立WebSocket连接,在网页请求服务器中的HTTP请求中会带有特殊的Header
例如:connection:upgrade upgrade:websocket;
主要是告诉服务器进行协议的升级(HTTP协议升级为WebSocket)
如果服务器支持,返回特殊的HTTP响应,状态码就是101;
如下图所示:
📚️2.WebSocket编码
🚀2.1后端服务器
代码如下:
@Component
public class TestAPI extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("连接成功");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("收到消息:"+message.getPayload());
session.sendMessage(message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("连接异常");
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("断开连接");
}
}
继承,TextWebSocketHandler,大致就是实现了一个简单的 WebSocket 服务器端处理器,它可以处理客户端的连接建立、文本消息接收、连接错误和连接关闭等事件,并做出相应的处理。主要功能是在连接建立、收到消息、连接异常和连接关闭时打印相应的提示信息,并且会将客户端发送的文本消息原样返回给客户端。(服务器要做的事)
配置到spring中:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private TestAPI testAPI;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(testAPI,"/test");
}
}
大致就是添加websocket的处理到spring中,注入对象,以及路径,那么前端访问时的路径就必须是这个“ / test ”;
🚀2.2前端客户端
代码如下:
<body>
<input type="text" id="message">
<button id="submit">提交</button>
<script>
// 创建 websocket 实例
let websocket = new WebSocket("ws://127.0.0.1:8080/test");
// 需要给实例挂载一些回调函数
websocket.onopen = function (){
console.log("建立连接")
}
websocket.onmessage = function (e){
console.log("收到消息:"+e.data)
}
websocket.onerror = function (){
console.log("连接异常")
}
websocket.onclose = function (){
console.log("断开连接")
}
let input = document.querySelector('#message')
let button = document.querySelector('#submit')
button.onclick = function (){
console.log("发送消息: " + input.value);
websocket.send(input.value);
}
</script>
</body>
ws:// 是 WebSocket 协议的前缀,127.0.0.1 是本地回环地址,8080 是服务器监听的端口号,/test 是具体的路径。
挂载回调函数:
onopen函数:即WebSocket 连接成功建立时,会触发onopen事件。
onmessage函数:客户端接收到服务器发送的消息时,会触发onmessage事件。事件处理函数的参数e是一个MessageEvent对象,通过e.data可以获取服务器发送的消息内容
onerror:即当 WebSocket 连接过程中出现错误时,会触发这个事件;
onclose:当 WebSocket 连接关闭时,会触发onclose事件;
websocket.send(input.value)方法将输入框中的消息发送给 WebSocket 服务器;
🚀2.3运行日志
当我们运行后,前后端运行日志如下所示:
前端
后端
这里在服务器收到uu们好后,就直接无处理直接发送信息给客户端,所以我们根据这里的情况,在服务器收到客户端1消息后,直接消息推送,实时更新数据发送给客户端2;
📚️3.总结
本期主要讲解了传统HTTP请求的情况,以及适应环境,如何使用HTTP请求达到消息推送的模拟;以及主要讲解了WebSocket可以解决的情况,基本介绍,和WebSocket实现消息推送的代码示范;
🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!
💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。
😊😊 期待你的关注~~~