springboot整合websocket(详解、教程、代码)

这篇具有很好参考价值的文章主要介绍了springboot整合websocket(详解、教程、代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

springboot整合websocket(教程及代码)

大家好,我是酷酷的韩~
springboot整合websocket,websocket,1024程序员节,springboot,websocket,教程详解,代码
1.websocket定义

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。websocket 协议是在 http 协议上的一种补充协议,是 html5 的新特性,是一种持久化的协议。

2.websocket工作原理:

握手(建立连接)

web浏览器和服务器都必须使用websocket来建立维护连接,也可以理解为HTTP握手 (handshake)和TCP数据传输
(1)浏览器向http一样发起一个请求,等待服务器响应
(2)服务器返回握手响应,告诉浏览器将后续的数据按照websocket的制定格式传输过来
(3)服务器接收到了之后,服务器与浏览器之间连接不中断,此时连接已经是双工的了
(4)浏览器和服务器由任何需要传输的数据时使用长连接来进行数据传递;

数据传输

一旦WebSocket客户端、服务端建立连接后,后续的操作都是基于数据帧的传递。这样做有几个好处:
1.数据可以进行分片传输,每条消息可能被切分成多个数据帧,这样就不用考虑数据大小导致的长度标志位不足够的情况。
ps :FIN=1表示当前数据帧为消息的最后一个数据帧,此时接收方已经收到完整的消息,可以对消息进行处理。FIN=0,则接收方还需要继续监听接收其余的数据帧;
2. 和http的chunk一样,可以边生成数据边传递消息,即提高传输效率;

3.websocket优点:

(1)较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
(2)更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
(3)保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
(4)更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
(5)可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
(6)更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

4.websocket应用

(1)系统实时通告
(2)即时聊天
(3)弹幕
(4)实时数据更新:比如体育实况更新、股票基金报价实时更新
(5)代替轮询,提高效率。

5.springBoot集成

5.1pom依赖

  <!--webSocket-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>

5.2websocket配置类:

package com.loit.park.common.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author hanjinqun
 * @date 2022/10/24
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {

        return new ServerEndpointExporter();
    }
}

5.3websocket操作类

注意:@ServerEndpoint路径支持自定义

package com.loit.park.common.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author hanjinqun
 * @date 2022/10/24
 * websocket操作类
 */
@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocketServer {
    /**
     * 日志工具
     */
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 用来存放每个客户端对应的MyWebSocket对象
     */
    private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    /**
     * 用来存在线连接用户信息
     */
    private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<String, Session>();

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        try {
            this.session = session;
            this.userId = userId;
            webSockets.add(this);
            sessionPool.put(userId, session);
            logger.info("【websocket消息】有新的连接,总数为:" + webSockets.size());
        } catch (Exception e) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            sessionPool.remove(this.userId);
            logger.info("【websocket消息】连接断开,总数为:" + webSockets.size());
        } catch (Exception e) {
        }
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message) {
        logger.info("【websocket消息】收到客户端消息:" + message);
    }

    /**
     * 发送错误时的处理
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("用户错误,原因:" + error.getMessage());
        error.printStackTrace();
    }

    /**
     * 此为广播消息
     */
    public void sendAllMessage(String message) {
        logger.info("【websocket消息】广播消息:" + message);
        for (WebSocketServer webSocket : webSockets) {
            try {
                if (webSocket.session.isOpen()) {
                    webSocket.session.getAsyncRemote().sendText(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 此为单点消息
     */
    public void sendOneMessage(String userId, String message) {
        Session session = sessionPool.get(userId);
        if (session != null && session.isOpen()) {
            try {
                logger.info("【websocket消息】 单点消息:" + message);
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 此为单点消息(多人)
     */
    public void sendMoreMessage(String[] userIds, String message) {
        for (String userId : userIds) {
            Session session = sessionPool.get(userId);
            if (session != null && session.isOpen()) {
                try {
                    logger.info("【websocket消息】 单点消息:" + message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

重要类方法说明:
(1)@ServerEndpoint(“/api/pushMessage/{userId}”) 前端通过此 URI 和后端交互,建立连接
(2)@Component 不用说将此类交给 spring 管理
(3)@OnOpen websocket 建立连接的注解,前端触发上面 URI 时会进入此注解标注的方法
(4)@OnMessage 收到前端传来的消息后执行的方法
(5)@OnClose 顾名思义关闭连接,销毁 session

5.4前端测试代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket通讯</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
    let socket;
    function openSocket() {
		const socketUrl = "ws://localhost:8003/websocket/admin";
        console.log(socketUrl);
        if(socket!=null){
            socket.close();
            socket=null;
        }
        socket = new WebSocket(socketUrl);
        //打开事件
        socket.onopen = function() {
            console.log("websocket已打开");
        };
        //获得消息事件
        socket.onmessage = function(msg) {
            console.log(msg.data);
            //发现消息进入,开始处理前端触发逻辑
        };
        //关闭事件
        socket.onclose = function() {
            console.log("websocket已关闭");
        };
        //发生了错误事件
        socket.onerror = function() {
            console.log("websocket发生了错误");
        }
    }
    function sendMessage() {

        socket.send('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
        console.log('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
    }
</script>
<body>
<p>【socket开启者的ID信息】:<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【客户端向服务器发送的内容】:<div><input id="toUserId" name="toUserId" type="text" value="20">
    <input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>【操作】:<button><a onclick="openSocket()">开启socket</a></button>
<p>【操作】:<button><a onclick="sendMessage()">发送消息</a></button>
</body>

</html>

5.5模拟发送数据接口

package com.loit.park.modules.controller.websocket;

import com.loit.park.common.constant.BusinessConstants;
import com.loit.park.common.websocket.WebSocketServer;
import com.loit.test1.common.json.AjaxJson;
import com.loit.test1.common.json.LoitStatusMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author hanjinqun
 * @date 2022/10/24
 * websocket接口
 */
@RestController
@RequestMapping(value = "/api/v1/websocket")
@Api(tags = "websocket接口", value = "AlarmDpController")
public class WebSocketController {
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 模拟数据发送
     */
    @ApiOperation(value = "模拟数据发送", notes = "模拟数据发送")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "message", value = "模拟消息", required = true, dataType = "String"),
    })
    @RequestMapping(value = "/sendTestMessage", method = RequestMethod.GET)
    public AjaxJson sendTestMessage(String message) {
        AjaxJson ajaxJson = new AjaxJson();
        try {
            webSocketServer.sendAllMessage(message);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxJson.returnExceptionInfo(LoitStatusMsg.LOIT_USER_LOGIN_FAIL);
        }
        return ajaxJson;
    }
}

5.6模拟操作
springboot整合websocket,websocket,1024程序员节,springboot,websocket,教程详解,代码

亲爱的,你要努力,你想要的的,你要自己给自己。 ------酷酷的韩文章来源地址https://www.toymoban.com/news/detail-780889.html

到了这里,关于springboot整合websocket(详解、教程、代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSocket--整合springboot

    目录 握手拦截器 WebSocket处理程序 HttpSessionHandshakelnterceptor (抽象类):   握手拦截器,在握手前后添加操作 AbstractWebSocketHandler (抽象类) :   WebSocket处理程序,监听连接前,连接中,连接后WebSocketConfigurer (接口):    配置程序,比如配置监听哪个端口,上面的握手拦截器,处理

    2024年01月16日
    浏览(60)
  • SpringBoot整合Websocket(Java websocket怎么使用)

    WebSocket 是一种基于 TCP 协议的全双工通信协议,可以在浏览器和服务器之间建立 实时、双向的数据通信 。可以用于在线聊天、在线游戏、实时数据展示等场景。与传统的 HTTP 协议不同,WebSocket 可以保持 长连接 ,实时传输数据,避免了频繁的 HTTP 请求和响应,节省了网络带

    2024年02月10日
    浏览(40)
  • [超详细]SpringBoot整合WebSocket

    WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它允许在浏览器和服务器之间进行实时的、双向的通信。相对于传统的基于请求和响应的 HTTP 协议,WebSocket 提供了一种更有效、更实时的通信方式,适用于需要实时更新、实时通知和实时交互的应用。 WebSocket 的一些关

    2024年02月11日
    浏览(40)
  • 【WebSocket】SpringBoot整合WebSocket实现聊天室(一)

    目录 一、准备 1、引入依赖 2、创建配置类 二、相关注解 首先我们需要在项目中引入依赖,有两种方式。第一种我们可以在创建Spring Boot项目时搜索WebSocket然后勾选依赖 第二种是我们可以直接在项目的pom.xml文件中插入以下依赖 我们需要进行如下配置 ServerEndpointExporter 是一个

    2024年02月13日
    浏览(45)
  • 【十六】springboot整合WebSocket(超详细)

     springboot篇章整体栏目:  【一】springboot整合swagger(超详细 【二】springboot整合swagger(自定义)(超详细) 【三】springboot整合token(超详细) 【四】springboot整合mybatis-plus(超详细)(上) 【五】springboot整合mybatis-plus(超详细)(下) 【六】springboot整合自定义全局异常处

    2023年04月09日
    浏览(37)
  • WebSocket整合springboot显示进度条

    SpringBoot整合WebScoket显示进度条 - 钟小嘿 - 博客园 对于大文件上传解析,若直接上传,会超时,可使用WebSocket长链接方式实时显示文件的上传状态,实际上是从文件上传到内容解析完成存入数据库的过程,各个阶段的进度可自定义。 本文使用SpringBoot+WebSocket+vue2.0+Element+nginx实

    2024年02月14日
    浏览(41)
  • Springboot 整合 WebSocket ,使用STOMP协议 ,前后端整合实战 (一)(1)

    server: port: 9908 3.WebSocketConfig.java import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springfra

    2024年04月25日
    浏览(44)
  • (一)SpringBoot 整合WebSocket 前端 uniapp 访问

    第一次使用WebSocket,所以最需要一个及其简单的例子,跑通之后,增加自己对该技术的理解。(技术基础介绍就免掉了,后面再补)  案例逻辑:目前只有一个用户,而且是一个用户给服务器发送数据,服务给该用户返回数据 此处的逻辑一共三步 第一步,添加依赖项 第二步

    2024年02月10日
    浏览(40)
  • SpringBoot+Vue整合WebSocket实现实时通讯

            在开发过程中,我们经常遇到需要对前台的列表数据,实现实时展示最新的几条数据,或者是调度的任务进度条实现实时的刷新......,而对于这种需求,无状态的http协议显然无法满足我们的需求,于是websocket协议应运而生。websocket协议本质上是一个基于tcp的协议

    2024年02月13日
    浏览(40)
  • SpringBoot整合Netty+Websocket实现消息推送

           Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。以下是Netty的主要优势: 高性能 :Netty基于NIO(非阻塞IO)模型,采用事件驱动的设计,具有高性能的特点。它通过零拷贝技术、内存池化技术等手段,进一步提高

    2024年01月20日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包