利用WebSocket +MQ发送紧急订单消息,并在客户端收到消息的用户的页面自动刷新列表

背景:在原有通知公告的基础上,把通知公共的推送服务修改为其他业务收到紧急订单发送公告到消息队列MQ,然后在js中创建一个socket去监听公告,收到公告后刷新所有在订单页面的用户的页面列表(重点就是用户在收到紧急订单时能及时刷新页面并播报语音),语音播报功能可参考我以前的博文,当前功能只是在原有功能的基础上添加接收到公告时刷新列表(刷新列表完成后就会自动播报语音,这是之前已经完成的功能)

maven依赖:

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

注意事项: 一个系统建议只调用一次 creatSocket()方法,否则创建多个 socket实例就最好是创建多个creatSocket()方法,否则多次创建实例都会接收到相同的广播没有意义

1. WebSocketController.java的修改:

private AmqpTemplate amqpTemplate;
        
@PostMapping("/sendEkanbanYouXian")  //不能在列表刷新的地方触发推送  ,需求页面刷新时发送广播会触发所有人都刷新页面,所有人刷新又会触发所有人再次发送广播,因此造成死循环
public String sendEkanbanYouXian(String msg) {
    // 此处进行数据库操作  ----目前省略,待有需要再加进去
    //WebSocketServer.sendInfo(form.getMessage());//只能推送给一台服务器的用户(193/4)
    this.amqpTemplate.convertAndSend("fanout.exchange.msg","", msg); //使用队列给所有用户发送信息
    return "广播推送成功【" + msg + "】";
}

2. 提交紧急订单的js:

$.post("/socket/sendEkanbanYouXian", {msg: jiajiText}, function(res) { //业务js中把需要广播的消息发送到消息队列
    layer.msg(res);
});

3.js中创建Socket实例(用于监听广播)

var socket;
function creatSocket(){
    if (typeof (WebSocket) == "undefined") {
        console.log("您的浏览器不支持WebSocket");
    } else {
        console.log("您的浏览器支持WebSocket");
        //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接  
        //等同于socket = new WebSocket("ws://localhost:8083/checkcentersys/websocket/20");  
        var curWwwPath = window.document.location.href;// 当前网址
        // 获取主机地址
        var pathName = window.document.location.pathname;
        var pos = curWwwPath.indexOf(pathName);
        var localhostPath = curWwwPath.substring(0, pos);
        var socketPath = localhostPath.replace('http','ws');
        //用ajax同步取IP
        var serverIP="";
        var clientIP="";
        var postData = {};
                
        $.ajax({
            type : "get",
            url : "/socket/getServerIp",
            data : postData,
            async: false,
            cache : false,
            success : function(data) {
                if (data != null) {serverIP = data; }else{alert("取不到ServerIP");}
            },
            error : function(data) { alert("取ServerIP异常!");}
        });
        
        $.ajax({
            type : "get",
            url : "/socket/getClientIp",
            data : postData,
            async: false,
            cache : false,
            success : function(data) {
                if (data != null) {clientIP = data;} else{alert("取不到ClientIP");}
            },
            error : function(data) {alert("取ClientIP异常!");}
        });
        
        socketPath = "ws://"+serverIP+":8101";    //socketPath = "ws://172.16.183.127:8101";
        var loginUserId = document.getElementById("loginUserId").value;
        socket = new WebSocket(socketPath + "/websocket/" + clientIP + "/" + loginUserId);

        //打开事件  
        socket.onopen = function() {console.log("Socket 已打开");};    
        
        socket.onmessage = function(msg) {//获得消息事件 (监听广播) 
            $("#mteSearchBtn").click();//收到广播触发页面列表的刷新
            if (msg.data != "连接成功" && msg.data !="") {//发现消息进入    开始处理前端触发逻辑
               layer.open({
                    type: 1,
                    offset: 'rt',
                    anim: 'slideDown', // 从上往下(右上角)
                    area: ['30%', '160px'],
                    skin: 'layui-layer-molv',
                    shade: 0.1,
                    shadeClose: true,
                    id: 'ID-demo-layer-direction-t',
                    content: '<div style="padding: 16px;">'+msg.data+'</div>'
                });
            }
        };
        //关闭事件  
        socket.onclose = function() {console.log("Socket已关闭");};
        //发生了错误事件  
        socket.onerror = function() {alert("Socket发生了错误");}//此时可以尝试刷新页面
    }
} 

重点:主要就是监听到广播后,调用页面的搜索按钮,进行从新加载列表
 

4. 上面的弹出层使用的是layui框架的弹出层,但是不太方便使用thymeleaf设置查看权限(例如我的加急订单只给仓库人员查看,其他人不需要看,因此弹出层我需要设置权限,那就使用原生弹出层):

        4.1 替换上面的JS接收socket的部分(重点就是弹出层的动画效果):

socket.onmessage = function(msg) {//获得消息事件 (监听广播)
            if (msg.data != "连接成功" && msg.data !="") {//发现消息进入    开始处理前端触发逻辑
                $("#socket").fadeIn(3000);
                $("#socketmsg").html(msg.data);
                $("#mteSearchBtn").click();//收到消息就立马让页面触发刷新 (物料需求页面列表刷新,页面刷新自然就有语音,因此这个功能因为这句代码导致暂时只能适用于 物料需求页面),$("#mteSearchBtn")必须是这样触发,不能直接写mteSearchBtn.click否则无效
                // 开启定时器
                function startTimes() {
                    var i = 10;
                    var timer = window.setInterval(function() {
                        console.log('还有' + (--i) + '秒关闭socket广播窗口!');
                        if (i <= 0) {
                            window.clearInterval(timer);
                            console.log('已关闭socket广播窗口!');
                            $("#socket").fadeOut(3000);
                            $("#socket").fadeTo("3000", 0.7);
                        }
                    }, 1000);
                }
                startTimes();
            }
			getOnlineCountJS(); //获取在线人数
		};

4.2 html

<div id="socket" th:if="${session.userpermis == 1 || session.ekanbanruku == 1 || session.ekanbanruku == '1'}"> <!--只有仓库的人才能看到-->
		<input type="hidden" id="sockethidIP" th:value="${serverIp}" />
		<div id="socketTitle">消息通知
			<span id ="socketClose">
				<img onclick="hideSocketDialog();" alt="" src="css/images/close.png">
			</span>
		</div>
		<div id = "socketmsg">
		</div>
	</div>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往事不堪回首..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值