SpringBoot + webSocket + stomp +thymeleaf 推流

一、引入依赖

<!-- websocket推流-->

    <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-websocket</artifactId>

    </dependency>

   

<!--thymeleaf模板-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

  

   

二、后端配置

1、新建一个 WebSocketStompConfig 类来实现 WebSocketMessageBrokerConfigurer

//交给SpringBoot管理

@Configuration

//注解开启使用STOMP协议来传输基于代理(message broker)的消息

@EnableWebSocketMessageBroker

@Order(1)

public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {

   

    /**

     * 注册stomp的端点(endpoint),并映射指定的url

     */

    @Override

    public void registerStompEndpoints(StompEndpointRegistry registry) {

        /* 允许使用socketJs方式访问,访问点为webSocketServer,允许跨域

         在网页上我们就可以通过这个链接

         http://localhost:8080/webSocket/server

         来和服务器的WebSocket连接*/

   

        //注册一个STOMP的endpoint,并指定使用SockJS协议

        registry.addEndpoint("/websocket/server").setAllowedOrigins("*").withSockJS();

    }

   

    /**

     * 配置信息代理

     */

    @Override

    public void configureMessageBroker(MessageBrokerRegistry registry) {

        // 订阅Broker名称

        //两个域上可以向客户端发消息

        registry.enableSimpleBroker("/queue", "/topic", "/user");

          

        // 全局使用的消息前缀(客户端订阅路径上会体现出来)

        //客户端向服务端发送时的主题上面需要加"/app"作为前缀

//        registry.setApplicationDestinationPrefixes("/app");

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

//        registry.setUserDestinationPrefix("/user");

    }

   

三、后端向前端推流

1、创建Controller控制层

@Slf4j

@Controller

@Api(tags = "webSocket推流")

public class WebSocketRest{

   

    //依赖messageTemplate发送模板

    @Autowired

    private SimpMessagingTemplate messagingTemplate ;

   

    /*

    * 跳转webSocket测试页面

    * */

    @GetMapping("webPage")

    @ApiOperation(value = "webPage 页面跳转")

    public String webPage(){

        log.info("forward:web");

        return "webscoket";

    }

}

   

2、创建service服务层 (订阅后)

@Service

public class WebSocketService {

    @Resource

    private SimpMessagingTemplate messagingTemplate ;

   

    /*

    * 每隔1s向 "/topic/hello" 中 推送信息

    * */

    @Scheduled(fixedDelay = 1000)

    public String sendTest01(){

        messagingTemplate.convertAndSend("/topic/hello",new ServerMessage("hello webSocket !!! >>> hello ")) ;

        return "message" ;

    }

}

   

3、编写前端页面

<!DOCTYPE html>

   

<html xmlns:th="http://www.thymeleaf.org">

   

<head>

   <meta charset="UTF-8" />

   <title>Spring Boot+WebSocket+广播式(点对点)</title>

</head>

<body onload="disconnect()">

<noscript>

<h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2>

</noscript>

<div>

   <div>

     <button id="hello" onclick="hello();">hello连接</button>

     <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>

   </div>

</div>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/sockjs-client/1.5.0/sockjs.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/stomp.js/2.3.3/stomp.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js}"></script>

<script type="text/javascript">

   var stompClient = null;

    function hello() {

     //若前后端分离,url要写全,若在一个项目内,只写/websocket/server就行

     var url = "http://ip:8080/websocket/server"

     var socket = new SockJS(url); //链接SockJS 的endpoint 名称为后台声明的"/websocket/server"

     stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端

     stompClient.connect({}, function(frame) {//链接Web Socket的服务端。

        console.log('Connected: ' + frame);

       //广播式发送,订阅地址不需要加唯一标识;点对点发送,可自定义唯一标识

       var subUrl= '/topic/hello';

       stompClient.subscribe(subUrl, function(respnose){ //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。

         showResponse(JSON.parse(respnose.body).name);

       });

     });

   }

   

    //断开连接

    function disconnect() {

        if (stompClient != null) {

      stompClient.disconnect();

       }

       setConnected(false);

       console.log("Disconnected");

    }

 </script>

</body>

</html>

   

4、效果

   

五、前端向后端推送消息

   

1、创建Controller控制层

@Slf4j

@Controller

@Api(tags = "webSocket推流")

public class WebSocketRest{

   

    //依赖messageTemplate发送模板

    @Autowired

    private SimpMessagingTemplate messagingTemplate ;

   

    /*

    * 跳转webSocket测试页面

    * */

    @GetMapping("webPage")

    @ApiOperation(value = "webPage 页面跳转")

    public String webPage(){

        log.info("forward:web");

        return "webscoket";

    }

   

    /*

    *   接收到 客户端的消息

    * */

    @ResponseBody

    @MessageMapping(value = "/welcome")

    public void userChat(Message message) throws Exception {

        String url = "/topic/getResponse/"+message.getName();

        messagingTemplate.convertAndSend(url, "welcome!");

    }

}

   

2、编写前端页面

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta charset="UTF-8" />

    <title>Spring Boot+WebSocket+广播式(点对点)</title>

   

</head>

<body onload="disconnect()">

<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>

<div>

    <div>

<!--        <button id="connect" onclick="connect();">connect连接</button>-->

        <button id="hello" onclick="hello();">hello连接</button>

        <button id="serverReturnMessage" onclick="serverReturnMessage();">serverReturnMessage连接</button>

        <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>

   

    </div>

    <div id="conversationDiv">

        <label>输入你的信息</label><input type="text" id="name" />

        <button id="sendName" onclick="sendName();">发送</button>

        <p id="response"></p>

    </div>

</div>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/sockjs-client/1.5.0/sockjs.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/stomp.js/2.3.3/stomp.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js}"></script>

<script type="text/javascript">

    var stompClient = null;

   

    function setConnected(flag) {

        // document.getElementById('connect').disabled = flag;

        document.getElementById('disconnect').disabled = !flag;

        document.getElementById('conversationDiv').style.visibility = flag ? 'visible' : 'hidden';

    }

   

         

    function serverReturnMessage() {

        //若前后端分离,url要写全,若在一个项目内,只写/websocket/server就行

        var url = "http://ip:8080/websocket/server"

        var socket = new SockJS(url); //链接SockJS 的endpoint 名称为后台声明的"/websocket/server"

        stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端

        stompClient.connect({}, function(frame) {//链接Web Socket的服务端。

            setConnected(true);

            console.log('Connected: ' + frame);

            //广播式发送,订阅地址不需要加唯一标识;点对点发送,可自定义唯一标识

            var subUrl= '/topic/serverReturnMessage';

            stompClient.subscribe(subUrl, function(respnose){ //订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。

                showResponse(JSON.parse(respnose.body).name);

            });

        });

    }

   

    //断开连接

    function disconnect() {

        if (stompClient != null) {

            stompClient.disconnect();

        }

        setConnected(false);

        console.log("Disconnected");

    }

   

    function showResponse(message) {

        var response = $("#response");

        console.log(message);

    }

//向stompClient发送请求

    function sendName() {

        var name = $('#name').val();

        //通过stompClient.send 向/welcome 目标 发送消息,这个是在控制器的@messageMapping 中定义的。

        //在这里,可根据业务自定义json,甚至可以把订阅地址的唯一标识在此传入给后台解析

        var obj = JSON.stringify({'name': name, 'retailmId': '001'})

   

        stompClient.send("/sendTest", {}, obj);

    }

</script>

</body>

</html>

   

3、效果

六、点对点推流

1、修改WebSocketStompConfig配置文件。将标记行注释取消。

   

2、创建服务层

@Service

public class WebSocketService {

    @Resource

    private SimpMessagingTemplate messagingTemplate ;

   

   

    /*

     *点对点消息推送

     * */

    @Scheduled(fixedDelay = 1000)

    public void userChat() throws Exception {

        String url = "/user/nodeSendNode/";

        String username = "zhangsan";

        messagingTemplate.convertAndSendToUser(username, url ," 点 对 点  推送!");

    }

}

   

3、编写前端页面

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta charset="UTF-8" />

    <title>Spring Boot+WebSocket+广播式(点对点)</title>

   

</head>

<body onload="disconnect()">

<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>

<div>

    <div>

        <button id="nodeSendNode" onclick="nodeSendNode();">nodeSendNode连接</button>

        <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>

    </div>

</div>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/sockjs-client/1.5.0/sockjs.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/stomp.js/2.3.3/stomp.min.js}"></script>

<script th:src="@{https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js}"></script>

<!--<script th:src="@{sockjs.js}"></script>

<script th:src="@{stomp.js}"></script>

<script th:src="@{jquery.js}"></script>-->

<script type="text/javascript">

    var stompClient = null;

   

    function setConnected(flag) {

        // document.getElementById('connect').disabled = flag;

        document.getElementById('disconnect').disabled = !flag;

        document.getElementById('conversationDiv').style.visibility = flag ? 'visible' : 'hidden';

    }

   

    //点对点

    function nodeSendNode() {

        //配置用户名 用于接收但对点消息

        var username = 'zhangsan';

        //若前后端分离,url要写全,若在一个项目内,只写/websocket/server就行

        var url = "http://10.20.37.64:8080/websocket/server"

        var socket = new SockJS(url); //链接SockJS 的endpoint 名称为后台声明的"/websocket/server"

        stompClient = Stomp.over(socket);//使用stomp子协议的WebSocket 客户端

        stompClient.connect({}, function(frame) {//链接Web Socket的服务端。

            setConnected(true);

            console.log('Connected: ' + frame);

            //点对点发送,订阅地址不需要加唯一标识;点对点发送,可自定义唯一标识

            var subUrl= '/user/nodeSendNode/';

//订阅/topic/getResponse 目标发送的消息。这个是在控制器的@SendTo中定义的。

            stompClient.subscribe('/user/'+ username +subUrl, function(respnose){                

 console.log(respnose.body);

            });

        });

    }

   

    //断开连接

function disconnect() {

        if (stompClient != null) {

            stompClient.disconnect();

        }

        setConnected(false);

        console.log("Disconnected");

    }

   

    function showResponse(message) {

        var response = $("#response");

        console.log(message);

    }

   </script>

</body>

</html>

   

4、效果

posted @ 2021-01-23 14:59  黑质白章  阅读(944)  评论(1编辑  收藏  举报