您的位置:首页 > 游戏 > 游戏 > websocket

websocket

2024/10/6 18:20:35 来源:https://blog.csdn.net/Casual_Lei/article/details/139815092  浏览:    关键词:websocket

websocket

  • websocket概述
  • websocket入门
  • springboot整合Websocket

websocket概述

1 为什么需要websocket?

​ 我们在上网时经常会遇到一些情况,就是页面没有刷新,但是一些数据会发生了改变,比如:在邮箱页面当收到新邮件时,我们并没有刷新页面,但是却会主动提示有新邮件达到,并会将未读邮件的数量+1。或者是在一些购物网站,当有新消息时并没有刷新页面,却提示了我们有新消息未读。

​ 那像这样的业务场景是怎么实现的呢?为什么页面没有刷新,浏览器却提醒我们有新消息呢?

在这里插入图片描述

在这里插入图片描述

​ 解决方案:

1、采用轮询的方式。即:通过js不断的请求服务器,查看是否有新数据,如果有,就获取到新数据。这种解决方法是否存在问题呢?

​ 当然是有的,如果服务端一直没有新的数据,那么js也是需要一直的轮询查询数据,这就是一种资源的浪费。

2、使用webSocket来解决

那什么是websocket呢?

2 什么是WebSocket?

​ WebSocket是一种网络通信协议,它允许在单个TCP连接上进行全双工通信。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

​ WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。这种技术通过HTTP/1.1协议的101状态码进行握手,实现了一种长连接,使得双方可以实时地进行信息交换。

全双工(Full Duplex)、半双工(Half Duplex)和单工(Simplex Communication)是数据通信中描述数据在线路上传输方向的不同方式。

  1. 全双工(Full Duplex): 全双工允许数据在两个方向上同时传输,即通信的双方可以同时发送和接收数据。这相当于两个单工通信方式的结合,数据在两个方向上可以同时流动。全双工通信在发送数据的同时也能够接收数据,两者同步进行。例如,我们平时打电话时,可以同时说话并听到对方的声音,这就是全双工通信的一个典型例子。
  2. 半双工(Half Duplex): 半双工通信是指数据可以沿两个方向传送,但同一时刻一个信道只允许单方向传送,因此又被称为双向交替通信。在半双工通信中,虽然数据可以在两个方向上传输,但在任何时刻只能由其中的一方发送数据,另一方接收数据。若要改变传输方向,需由开关进行切换。例如,无线对讲机就是一种半双工设备,在同一时间内只允许一方讲话。
  3. 单工(Simplex Communication): 单工通信模式的数据传输是单向的。通信双方中,一方固定为发送端,一方则固定为接收端。信息只能沿一个方向传输,使用一根传输线。移动通信按照用户的通话状态和频率使用的方法,可分为单工制、半双工制和双工制。例如,计算机与打印机之间的通信是单工模式,因为只有计算机向打印机传输数据,而没有相反方向的数据传输。

总结来说,全双工、半双工和单工是数据通信中描述数据在线路上传输方向的不同方式。全双工允许数据在两个方向上同时传输,半双工允许数据在两个方向上交替传输,而单工则只允许数据在一个方向上传输。

WebSocket具有以下特点:

  1. 双向通信:WebSocket协议支持客户端和服务器之间的双向通信,使得双方可以实时地进行信息交换。
  2. 实时性:WebSocket协议的设计目标就是提供实时的通信体验,因此它能够有效地减少延迟,提高通信效率。
  3. 持久连接:WebSocket协议使用TCP的持久连接,这意味着一旦建立了连接,服务器就可以主动推送信息给客户端,而不需要每次都进行握手和建立连接的过程。
  4. 兼容性:WebSocket协议具有良好的兼容性,它可以在不同的设备和浏览器上使用,包括移动设备和PC浏览器。
  5. 事件驱动:WebSocket协议是基于事件驱动的,这意味着它能够更好地处理异步操作和实时事件。

WebSocket的应用场景包括但不限于实时聊天、股票交易、实时地图等需要实时数据传输的应用。它相对于传统的轮询和Comet技术,能够更节省服务器资源和带宽,并且能够更实时地进行通讯。

3 http和webSocket的区别

http协议是短连接,因为请求之后,都会关闭连接,下次重新请求数据,需要再次打开链接。

在这里插入图片描述

WebSocket协议是一种长链接,只需要通过一次请求来初始化链接,然后所有的请求和响应都是通过这个TCP链接进行通讯。

在这里插入图片描述

总结:

1、http和websocket的相同点

​ 都是一样基于TCP的,都是可靠性传输协议。

​ 都是应用层协议。

2、 http和WebSocket的区别

​ WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。

​ WebSocket是需要浏览器和服务器握手进行建立连接的。而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。

联系

​ WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

4 浏览器对于webSocket的支持情况

​ 目前,基本上所有的主流浏览器都支持WebSocket。具体来说,Chrome从Chrome 4开始支持WebSocket,Firefox从Firefox 4开始支持,Safari从Safari 5开始支持,而Edge也支持WebSocket。这些浏览器都内置了对WebSocket协议的实现,使得开发者可以在网页中轻松地使用WebSocket进行实时通信。

在这里插入图片描述

网址: https://caniuse.com/?search=websocket

三 webSocket入门

1 websocket的相关注解说明

  • @ServerEndpoint(“/websocket/{uid}”)这个注解是写在类上面的申明这是一个websocket服务需要指定访问该服务的地址,在地址中可以指定参数,需要通过{}进行占位

  • @OnOpen用法:public void onOpen(Session session, @PathParam(“uid”) String uid) throws IOException{}该方法将在建立连接后执行,会传入session对象,就是客户端与服务端建立的长连接通道通过@PathParam获取url传递中的参数

  • @OnClose用法:public void onClose() {}该方法是在连接关闭后执行

  • @OnMessage用法:public void onMessage(String message, Session session) throws IOException {}该方法用于接收客户端发来的消息message:发来的消息数据session:会话对象(也是通道)

  • 发送消息到客户端用法:session.getBasicRemote().sendText(“你好”);通过session进行发送。

2 入门实现

创建一个Web项目

导包

<dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version><scope>provided</scope></dependency>

编写webSocket入门代码

package cn.ronghuanet;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;@ServerEndpoint("/websocket/{uid}")
public class MyWebSocket {@OnOpenpublic void onOpen(Session session, @PathParam("uid")String uid)throws Exception{session.getBasicRemote().sendText(uid+"欢迎你!成功连接到websocket");}@OnClosepublic void onClose(){System.out.println("关闭连接");}@OnMessagepublic void onMessage(String message,Session session)throws Exception{System.out.println("接收到消息"+message);session.getBasicRemote().sendText("你好,我已收到你的消息");}@OnErrorpublic void onError(Session session,Throwable throwable){System.out.println("出错了!!!!!");throwable.printStackTrace();}
}

写前端页面用来做测试

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script type="text/javascript">const socket = new WebSocket("ws://localhost:8080/websocket/1");socket.onopen = (ws) =>{console.log("建立连接!", ws);}socket.onmessage = (ws) =>{console.log("接收到消息 >> ",ws.data);}socket.onclose = (ws) =>{console.log("连接已断开!", ws);}socket.onerror = (ws) => {console.log("发送错误!", ws);}// 2秒后向服务端发送消息setTimeout(()=>{socket.send("发送一条消息试试");},2000);// 5秒后断开连接setTimeout(()=>{socket.close();},5000);
</script>
</body>
</html>

将项目部署到tomcat,访问页面测试

在这里插入图片描述

3 springboot整合WebScoekt

3.1 基本实现

创建新项目

导入依赖

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
</dependencies>

启动类

@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}

消息处理类,在spring中,处理消息的具体业务逻辑需要实现WebSocketHandler接口

/*** 在本类中接收前端传递的消息,进行处理*/
@Component
public class MyHandler extends TextWebSocketHandler {/*** 处理文本消息* @param session* @param message* @throws Exception*/@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {String payload = message.getPayload();System.out.println("接收到前端传递的消息-->"+payload);session.sendMessage(new TextMessage("===你好,我已经收到你的消息了======="));if(message.getPayload().equals("10")){for (int i = 0; i < 10; i++) {session.sendMessage(new TextMessage("返回第"+i+"条消息到前端"));Thread.sleep(1000);}}}/*** 建立连接之后* @param session* @throws Exception*/@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {System.out.println("uid==>"+session.getAttributes().get("uid"));System.out.println("欢迎你连接到websocket服务啊");}/*** 断开连接之后* @param session* @param status* @throws Exception*/@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {System.out.println("连接已经被关闭了..............");}
}

websocket配置类,在该类中配置handler的访问path以及允许访问的源等

/*** 注册websocket的处理类*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Autowiredprivate MyHandler myHandler;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler, "ws").setAllowedOrigins("*");}
}

编写前端用于测试

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>websocket测试页面</title>
</head>
<body><script type="text/javascript">const socket = new WebSocket("ws://localhost:8080/ws");socket.onopen = (ws) =>{console.log("和后端建立连接==>", ws);}socket.onmessage = (ws) =>{console.log("接收到后端返回来的消息==> ",ws.data);}socket.onclose = (ws) =>{console.log("连接已断开!", ws);}socket.onerror = (ws) => {console.log("发送错误!", ws);}// 2秒后向服务端发送消息setTimeout(()=>{socket.send("10");},5000);window.setInterval(() => {socket.send("后端你好,我是前端");},1000)// 5秒后断开连接/*setTimeout(()=>{socket.close();},5000);*/</script>
</body>
</html>

启动项目,在浏览器访问前端页面用于测试

在这里插入图片描述

在这里插入图片描述

3.2 webSocket拦截器

在Spring中提供了websocket拦截器,可以在建立连接之前写些业务逻辑,比如校验登录等。

@Component
public class MyHandleSnakeInterceptor implements HandshakeInterceptor {/*** 握手前* @param request* @param response* @param wsHandler* @param attributes* @return  true 建立连接   false 不满足条件,不建立连接* @throws Exception*/@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {System.out.println("准备握手了");attributes.put("uid", 10001);return true;}/*** 握手后* @param request* @param response* @param wsHandler* @param exception*/@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {System.out.println("握手成功了!!!!!!!");}
}

在配置类中配置该拦截器要作用于哪些Handler

 /*** 注册websocket的处理类*/@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {@Autowiredprivate MyHandler myHandler;@Autowiredprivate MyHandleSnakeInterceptor myHandleSnakeInterceptor;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler, "ws").setAllowedOrigins("*").addInterceptors(myHandleSnakeInterceptor);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com