SpringBoot集成WebSocket【基于STOMP协议】进⾏点对点
[⼀对⼀]和⼴播。。。
最近项⽬来了新需求,需要做⼀个实时推送的功能,服务器主动推送消息给客户端,在⽹上经过⼀轮搜查之后,确定使⽤WebSocket来进⾏开发。以前经常听说WebSocket的神奇之处,如今终于可以尝试使⽤它了。
1.浅谈WebSocket
WebSocket是在HTML5基础上单个TCP连接上进⾏全双⼯通讯的协议,只要浏览器和服务器进⾏⼀次握⼿,就可以建⽴⼀条快速通道,两者就可以实现数据互传了。说⽩了,就是打破了传统的http协议的⽆状态传输(只能浏览器请求,服务端响应),websocket全双⼯通讯,就是浏览器和服务器进⾏⼀次握⼿,浏览器可以随时给服务器发送信息,服务器也可以随时主动发送信息给浏览器了。对webSocket 原理有兴趣的客官,可以⾃⾏百度。
2.环境搭建
因为是根据项⽬的需求来的,所以这⾥我只介绍在SpringBoot下使⽤WebSocket的其中⼀种实现【STOMP协议】。因此整个⼯程涉及websocket使⽤的⼤致框架为SpringBoot+Maven+websocket,其他
框架的基础搭建,我这⾥就不说了,相信各位也都很熟悉,我就直接集成websocket了。
在l加上对springBoot对WebSocket的⽀持:
1<!-- webSocket -->
2<dependency>
3    <groupId>org.springframework.boot</groupId>
4    <artifactId>spring-boot-starter-websocket</artifactId>
5</dependency>
这样SpringBoot就和WebSocket集成好了,我们就可以直接使⽤SpringBoot提供对WebSocket操作的API了
3.编码实现
①在Spring上下⽂中添加对WebSocket的配置
介绍以上⼏个相关的注解和⽅法:
1.@EnableWebSocketMessageBroker:开启使⽤STOMP协议来传输基于代理(message broker)的消息,这时控制器⽀持使⽤@MessageMapping,就像使⽤@RequestMapping⼀样。
2.AbstractWebSocketMessageBrokerConfigurer:继承WebSocket消息代理的类,配置相关信息。
4. ableSimpleBroker("/topic","/user"); 配置⼀个/topic⼴播消息代理和“/user”⼀对⼀消息代理
5. registry.setUserDestinationPrefix("/user");点对点使⽤的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/②实现服务器主动向客户端推送消息
SpringBoot封装得太好,webSocket⽤起来太简单(好处:⽤起来⽅便,坏处:你不知道底层实现)
1.⼀对多的实现:
先上后台java的代码
1
import t.annotation.Configuration;2
import fig.MessageBrokerRegistry;3
import org.springframework.fig.annotation.AbstractWebSocketMessageBrokerConfigurer;4
import org.springframework.fig.annotation.EnableWebSocketMessageBroker;5
import org.springframework.fig.annotation.StompEndpointRegistry;6
7
/**8
* 配置WebSocket 9
*/10@Configuration 111314
@Override 15
//注册STOMP 协议的节点(endpoint),并映射指定的url 16
public void registerStompEndpoints(StompEndpointRegistry registry) {17
//注册⼀个STOMP 的endpoint,并指定使⽤SockJS 协议18
registry.addEndpoint("/endpointOyzc").setAllowedOrigins("*").withSockJS();19
}20
@Override 21
//配置消息代理(Message Broker)22
public void configureMessageBroker(MessageBrokerRegistry registry) {23
//点对点应配置⼀个/user 消息代理,⼴播式应配置⼀个/topic 消息代理24
//点对点使⽤的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/26
registry.setUserDestinationPrefix("/user");27    }28}//注解开启使⽤STOMP 协议来传输基于代理(messa
ge broker)的消息,这时控制器⽀持使⽤@MessageMapping,就像使⽤@RequestMapping ⼀样
12
@EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
1package com.cheng.sbjm.boot;
2
3import org.springframework.beans.factory.annotation.Autowired;
4import ssaging.simp.SimpMessagingTemplate;
5import org.springframework.scheduling.annotation.Scheduled;
6import org.springframework.stereotype.Controller;
7import com.cheng.sbjm.domain.User;
8
9@Controller
10public class WebSocketController {
11
12    @Autowired
13    private SimpMessagingTemplate template;
14
15    //⼴播推送消息
16    @Scheduled(fixedRate = 10000)
17    public void sendTopicMessage() {
18 System.out.println("后台⼴播推送!");
19 User user=new User();
20 user.setUserName("oyzc");
21 user.setAge(10);
22    vertAndSend("/topic/getResponse",user);
23    }
24}
简单介绍⼀下
1.SimpMessagingTemplate:SpringBoot提供操作WebSocket的对象
2.@Scheduled(fixedRate = 10000):为了测试,定时10S执⾏这个⽅法,向客户端推送
3.1参数⼀:客户端监听指定通道时,设定的访问服务器的URL
3.2参数⼆:发送的消息(可以是对象、字符串等等)
在上客户端的代码(PC现代浏览器)
html页⾯:
1<!DOCTYPE html>
2<html>
3  <head>
4    <title>websocket.html</title>
5    <meta name="keywords" content="keyword1,keyword2,keyword3">
6    <meta name="description" content="this is my page">
7    <meta name="content-type" content="text/html" charset="UTF-8">
8    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
9  </head>
10  <body>
11 <div>
12    <p id="response"></p>
13 </div>
14
15 <!-- 独⽴JS -->
16 <script type="text/javascript" src="jquery.min.js" charset="utf-8"></script>
17 <script type="text/javascript" src="webSocket.js" charset="utf-8"></script>
18 <script type="text/javascript" src="sockjs.min.js" charset="utf-8"></script>
19 <script type="text/javascript" src="stomp.js" charset="utf-8"></script>
20  </body>
21</html>
JS代码[webSocket.js]
1    var stompClient = null;
2    //加载完浏览器后调⽤connect(),打开双通道
3    $(function(){
4 //打开双通道
5 connect()
6    })
7    //强制关闭浏览器调⽤websocket.close(),进⾏正常关闭
8    unload = function() {
9    disconnect()
10    }
11    function connect(){
12        var socket = new SockJS('127.0.0.1:9091/sbjm-cheng/endpointOyzc'); //连接SockJS的endpoint名称为"endpointOyzc"
13        stompClient = Stomp.over(socket);//使⽤STMOP⼦协议的WebSocket客户端
14        t({},function(frame){//连接WebSocket服务端
15            console.log('Connected:' + frame);
16            //通过stompClient.subscribe订阅/topic/getResponse ⽬标(destination)发送的消息
17            stompClient.subscribe('/topic/getResponse',function(response){
18                showResponse(JSON.parse(response.body));
19            });
20        });
21    }
22
23    //关闭双通道
24    function disconnect(){
25        if(stompClient != null) {
26            stompClient.disconnect();
27        }
28        console.log("Disconnected");
29    }
30    function showResponse(message){
31        var response = $("#response");
32        response.append("<p>"+message.userName+"</p>");
33    }
值得注意的是,只需要在连接服务器注册端点endPoint时,写访问服务器的全路径URL:
其他监听指定服务器⼴播的URL不需要写全路径
stompClient.subscribe('/topic/getResponse',function(response){
showResponse(JSON.parse(response.body));
});
2.⼀对⼀的实现
websocket和socket
先上后台java的代码
1package com.cheng.sbjm.boot;
2
3import org.springframework.beans.factory.annotation.Autowired;
4import ssaging.simp.SimpMessagingTemplate;
5import org.springframework.scheduling.annotation.Scheduled;
6import org.springframework.stereotype.Controller;
7import com.cheng.sbjm.domain.User;
8
9
10@Controller
11public class WebSocketController {
12
13    @Autowired
14    private SimpMessagingTemplate template;
15
16    //⼀对⼀推送消息
17    @Scheduled(fixedRate = 10000)
18    public void sendQueueMessage() {
19 System.out.println("后台⼀对⼀推送!");
20 User user=new User();
21 user.setUserId(1);
22 user.setUserName("oyzc");
23 user.setAge(10);
UserId()+"","/queue/getResponse",user);
25    }
26}
简单介绍⼀下:
1.SimpMessagingTemplate:SpringBoot提供操作WebSocket的对象
2.@Scheduled(fixedRate = 10000):为了测试,定时10S执⾏这个⽅法,向客户端推送
3.1参数⼀:指定客户端接收的⽤户标识(⼀般⽤⽤户ID)
3.2参数⼆:客户端监听指定通道时,设定的访问服务器的URL(客户端访问URL跟⼴播有些许不同)
3.3参数三:向⽬标发送消息体(实体、字符串等等)
在上客户端的代码(PC现代浏览器)
html页⾯: