• 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项目

    导包

    
          javax
          javaee-api
          7.0
          provided
        
    

    编写webSocket入门代码

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

    写前端页面用来做测试

    
    
    
        
        Title
    
    
    
    
    
    

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

    在这里插入图片描述

    3 springboot整合WebScoekt

    3.1 基本实现

    创建新项目

    导入依赖

        
            org.springframework.boot
            spring-boot-starter-parent
            2.2.5.RELEASE
        
            
            
                org.springframework.boot
                spring-boot-starter-websocket
            
    
    

    启动类

    @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
         */
        @Override
        protected 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
         */
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            System.out.println("uid==>"+session.getAttributes().get("uid"));
            System.out.println("欢迎你连接到websocket服务啊");
        }
    
        /**
         * 断开连接之后
         * @param session
         * @param status
         * @throws Exception
         */
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            System.out.println("连接已经被关闭了..............");
        }
    }
    

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

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

    编写前端用于测试

    
    
    
        
        websocket测试页面
    
    
        
    
    
    

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

    在这里插入图片描述

    在这里插入图片描述

    3.2 webSocket拦截器

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

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

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

     /**
         * 注册websocket的处理类
         */
        @Configuration
        @EnableWebSocket
        public class WebSocketConfig implements WebSocketConfigurer {
        
            @Autowired
            private MyHandler myHandler;
        
            @Autowired
            private MyHandleSnakeInterceptor myHandleSnakeInterceptor;
        
            @Override
            public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
                registry.addHandler(myHandler, "ws").setAllowedOrigins("*")
                        .addInterceptors(myHandleSnakeInterceptor);
            }
        }
    
  • 相关阅读:
    操作指南|JumpServer用户权限体系的使用实践
    空字符串使用Equals方法导致NullPointException
    朝花夕拾——数据库基本概念及Mysql基本命令操作
    【小白使用-已验证】PhpStudy下载安装使用教程23.10.17
    nvm安装node npm没有被安装
    方舟单机/管理员特殊物品指令代码大全
    支持在线状态检查的仪表板miniboard
    JUC并发编程——集合类不安全及Callable(基于狂神说的学习笔记)
    人大金仓物理备份异机恢复
    谈谈Vue项目打包的方式
  • 原文地址:https://blog.csdn.net/Casual_Lei/article/details/139815092