为编程爱好者分享易语言教程源码的资源网
好用的代理IP,游戏必备 ____广告位招租____ 服务器99/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器
好用的代理IP,游戏必备 ____广告位招租____ 服务器低至38/年 ____广告位招租____ ____广告位招租____ 挂机,建站服务器

网站首页 > 网络编程 正文

Springboot 整合 WebSocket,使用STOMP协议,前后端整合实战

三叶资源网 2022-10-11 19:18:50 网络编程 338 ℃ 0 评论

1.后端整合websocket (STOMP协议)

2.群发、指定单发

3.前端简单页面示例(接收、发送消息)

1. pom.xml 核心依赖的导入:


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.application.yml (我就单纯设置一下端口)


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.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
 
 
/**
 * @Author JCccc
 * @Description   EnableWebSocketMessageBroker-注解开启STOMP协议来传输基于代理的消息,此时控制器支持使用@MessageMapping
 * @Date 2021/6/30 8:53
 */
 
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        //topic用来广播,user用来实现点对点
        config.enableSimpleBroker("/topic", "/user");
    }
 
    /**
     * 开放节点
     * @param registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册两个STOMP的endpoint,分别用于广播和点对点
 
 
        //广播
        registry.addEndpoint("/publicServer").setAllowedOrigins("*").withSockJS();
 
        //点对点
        registry.addEndpoint("/privateServer").setAllowedOrigins("*").withSockJS();
    }
 
 
}

4.推送消息的实体类 Message.java

/**
 * @Author JCccc
 * @Description
 * @Date 2021/8/20 9:26
 */
public class Message {
 
    /**
     * 消息编码
     */
    private String code;
 
    /**
     * 来自(保证唯一)
     */
    private String form;
 
    /**
     * 去自(保证唯一)
     */
    private String to;
 
    /**
     * 内容
     */
    private String content;
 
    public String getCode() {
        return code;
    }
 
    public void setCode(String code) {
        this.code = code;
    }
 
    public String getForm() {
        return form;
    }
 
    public void setForm(String form) {
        this.form = form;
    }
 
    public String getTo() {
        return to;
    }
 
    public void setTo(String to) {
        this.to = to;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setContent(String content) {
        this.content = content;
    }
}

5.前端简单调试页面

① publicExample.html 监听广播消息的测试页面

<html>
<head>
    <meta charset="UTF-8">
    <title>等系统推消息</title>
    <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
    <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.0.min.js"
            integrity="sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=" crossorigin="anonymous"></script>
 
    <script type="text/javascript">
        var stompClient = null;
 
        function setConnected(connected) {
            document.getElementById("connect").disabled = connected;
            document.getElementById("disconnect").disabled = !connected;
            $("#response").html();
        }
 
        function connect() {
 
             var socket = new SockJS("http://localhost:9908/publicServer");
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function (frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/all', function (response) {
                    var responseData = document.getElementById('responseData');
                    var p = document.createElement('p');
                    p.style.wordWrap = 'break-word';
                    p.appendChild(document.createTextNode(response.body));
                    responseData.appendChild(p);
                });
            },{});
        }
 
        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
        }
 
        function sendMsg() {
            var content = document.getElementById('content').value;
            stompClient.send("/all",{},JSON.stringify({'content': content}));
        }
    </script>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div>
    <div>
        <labal>连接广播频道</labal>
        <button id="connect" onclick="connect();">Connect</button>
        <labal>取消连接</labal>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
    <div id="conversationDiv">
        <labal>广播消息</labal>
        <input type="text" id="content"/>
        <button id="sendMsg" onclick="sendMsg();">Send</button>
 
    </div>
    <div>
        <labal>接收到的消息:</labal>
        <p id="responseData"></p>
 
    </div>
 
</div>
 
</body>
</html>

简析:

趁热打铁,我们模拟系统后端给前端推送广播消息,通过接口模拟:


TestController.java

/**
 * @Author JCccc
 * @Description
 * @Date 2021/8/20 8:53
 */
@Controller
public class TestController {
    @Autowired
    public SimpMessagingTemplate template;
 
    /**
     * 广播
     *
     * @param msg
     */
    @ResponseBody
    @RequestMapping("/pushToAll")
    public void subscribe( @RequestBody Message msg) {
        template.convertAndSend("/topic/all", msg.getContent());
    }
}

简析:

我们推送消息,直接用 SimpMessagingTemplate ,

用的是convertAndSend 广播方式推送到对于的主题目的地 destination 。

(可以看到其实还有convertAndSendToUser ,不着急,后面会说,这是发送给某个连接用户的)

直接把项目跑起来,打开页面开始测试:

我们先点击connect ,连接成功:

可以看到实际上stomp.min.js 最终也是转化成为 ws/wss这种方式成功连接:

调用测试接口,推送广播消息:


在console其实也能看到:

广播功能就到这,接下来是 点对点。

前端页面:

privateExample.html

<html>
<head>
    <meta charset="UTF-8">
    <title>聊起来</title>
    <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
    <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.0.min.js"
            integrity="sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=" crossorigin="anonymous"></script>
 
    <script type="text/javascript">
        var stompClient = null;
 
        function setConnected(connected) {
            document.getElementById("connect").disabled = connected;
            document.getElementById("disconnect").disabled = !connected;
            $("#response").html();
        }
 
        function connect() {
            var socket = new SockJS("http://localhost:9908/privateServer");
            stompClient = Stomp.over(socket);
            stompClient.heartbeat.outgoing = 20000;
            // client will send heartbeats every 20000ms
            stompClient.heartbeat.incoming = 0;
            stompClient.connect({}, function (frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/user/' + document.getElementById('user').value + '/message', function (response) {
                    var responseData = document.getElementById('responseData');
                    var p = document.createElement('p');
                    p.style.wordWrap = 'break-word';
                    p.appendChild(document.createTextNode(response.body));
                    responseData.appendChild(p);
                });
 
 
            });
 
        }
 
        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
 
        }
 
        function sendMsg() {
            var headers = {
                login: 'mylogin',
                passcode: 'mypasscode',
// additional header
                'accessToken': 'HWPO325J9814GBHJF933'
            };
            var content = document.getElementById('content').value;
            var to = document.getElementById('to').value;
            stompClient.send("/alone", {'accessToken': 'HWPO325J9814GBHJF933'}, JSON.stringify({
                'content': content,
                'to': to
            }));
        }
    </script>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div>
    <div>
        <labal>连接用户</labal>
        <input type="text" id="user"/>
        <button id="connect" onclick="connect();">Connect</button>
 
    </div>
 
    <div>
        <labal>取消连接</labal>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
 
    <div id="conversationDiv">
        <labal>发送消息</labal>
        <div>
            <labal>内容</labal>
            <input type="text" id="content"/>
        </div>
        <div>
            <labal>发给谁</labal>
            <input type="text" id="to"/>
        </div>
        <button id="sendMsg" onclick="sendMsg();">Send</button>
 
    </div>
    <div>
        <labal>接收到的消息:</labal>
        <p id="responseData"></p>
 
    </div>
</div>
 
</body>
</html>

简析:

趁热打铁,我们模拟系统后端给前端推送点对点消息(指定某个用户),通过接口模拟:

    /**
     * 点对点
     */
    @ResponseBody
    @RequestMapping("/pushToOne")
    public void queue(@RequestBody Message msg) {
        System.out.println("进入方法");
        /*使用convertAndSendToUser方法,第一个参数为用户id,此时js中的订阅地址为
        "/user/" + 用户Id + "/message",其中"/user"是固定的*/
        template.convertAndSendToUser(msg.getTo(), "/message", msg.getContent());
 
    }

用的是convertAndSendToUser 推送到指定的用户 ,对于的主题目的地 destination(/message)

也许看到这里,你会觉得很奇怪,为什么我们推的主题是 /message,但是前端订阅的却是


"/user/" + 用户Id + "/message"

其实spring还提供了一些好玩的注解,

@MessageMapping 这个注解是对称于 @EnableWebSocketMessageBroker

也就是说,如果我们使用@EnableWebSocketMessageBroker ,那么我们在接口上面其实就能直接使用 @MessageMapping。

来源:三叶资源网,欢迎分享,公众号:iisanye,(三叶资源网⑤群:21414575

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

百度站内搜索
关注微信公众号
三叶资源网⑤群:三叶资源网⑤群

网站分类
随机tag
SmartQQ协议源码腾讯滑块验证码模块源码mysql折线图源码正则编码转换医院信息管理系统sqlite之数据库独立Cookies图片进度条ACCESS操作键值排序伊对APP模块爱奇艺登录udp协议博彩数据拼多多下单GDI窗口位置控制模块QQ采集
最新评论