您的当前位置:首页正文

springboot+websocket+sockjs进行消息推送【基于STOMP协议】

2024-11-07 来源:个人技术集锦

1.浅谈WebSocket

WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就可以建立一条快速通道,两者就可以实现数据互传了。说白了,就是打破了传统的http协议的无状态传输(只能浏览器请求,服务端响应),websocket全双工通讯,就是浏览器和服务器进行一次握手,浏览器可以随时给服务器发送信息,服务器也可以随时主动发送信息给浏览器了。对webSocket原理有兴趣的客官,可以自行百度。

2.环境搭建

因为是根据项目的需求来的,所以这里我只介绍在SpringBoot下使用WebSocket的其中一种实现【STOMP协议】。因此整个工程涉及websocket使用的大致框架为SpringBoot+Maven+websocket,其他框架的基础搭建,我这里就不说了,相信各位也都很熟悉,我就直接集成websocket了。

在pox.xml加上对springBoot对WebSocket的支持:

<!-- webSocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
这样SpringBoot就和WebSocket集成好了,我们就可以直接使用SpringBoot提供对WebSocket操作的API了

3.编码实现

①在Spring上下文中添加对WebSocket的配置

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
 
/**
 * 配置WebSocket
 */
@Configuration
//注解开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
    @Override
    //注册STOMP协议的节点(endpoint),并映射指定的url
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册一个STOMP的endpoint,并指定使用SockJS协议
        registry.addEndpoint("/endpointOyzc").setAllowedOrigins("*").withSockJS();
    }
    @Override
    //配置消息代理(Message Broker)
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //点对点应配置一个/user消息代理,广播式应配置一个/topic消息代理
        registry.enableSimpleBroker("/topic","/user");
        //点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
        registry.setUserDestinationPrefix("/user");
    }
}
介绍以上几个相关的注解和方法:

1.@EnableWebSocketMessageBroker:开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样。

2.AbstractWebSocketMessageBrokerConfigurer:继承WebSocket消息代理的类,配置相关信息。

3.registry.addEndpoint("/endpointOyzc").setAllowedOrigins("*").withSockJS(); 添加一个访问端点“/endpointGym”,客户端打开双通道时需要的url,允许所有的域名跨域访问,指定使用SockJS协议。

4. registry.enableSimpleBroker("/topic","/user"); 配置一个/topic广播消息代理和“/user”一对一消息代理

5. registry.setUserDestinationPrefix("/user");点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/

 

②实现服务器主动向客户端推送消息

SpringBoot封装得太好,webSocket用起来太简单(好处:用起来方便,坏处:你不知道底层实现)

1.一对多的实现:

先上后台java的代码

package com.cheng.sbjm.boot;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import com.cheng.sbjm.domain.User;
 
@Controller
public class WebSocketController {
    
    @Autowired
    private SimpMessagingTemplate template;
    
    //广播推送消息
    @Scheduled(fixedRate = 10000)
    public void sendTopicMessage() {
    System.out.println("后台广播推送!");
    User user=new User();
    user.setUserName("oyzc");
    user.setAge(10);
        this.template.convertAndSend("/topic/getResponse",user);
    }
}
简单介绍一下

1.SimpMessagingTemplate:SpringBoot提供操作WebSocket的对象

2.@Scheduled(fixedRate = 10000):为了测试,定时10S执行这个方法,向客户端推送

3.template.convertAndSend("/topic/getResponse",new AricResponse("后台实时推送:,Oyzc!")); :直接向前端推送消息。

3.1参数一:客户端监听指定通道时,设定的访问服务器的URL

3.2参数二:发送的消息(可以是对象、字符串等等)

 

在上客户端的代码(PC现代浏览器)

html页面:

<!DOCTYPE html>
<html>
  <head>
    <title>websocket.html</title>    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html" charset="UTF-8">
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->    
  </head>  
  <body>
    <div>  
        <p id="response"></p>
    </div>
    
    <!-- 独立JS -->
    <script type="text/javascript" src="jquery.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="webSocket.js" charset="utf-8"></script>
    <script type="text/javascript" src="sockjs.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="stomp.js" charset="utf-8"></script>
  </body>
</html>

Top