当前位置: 首页 > news >正文

Springboot + Vue + WebSocket + Notification实现消息推送功能

实现功能

        基于Springboot与Vue架构,首先使用Websocket实现频道订阅,在实现点对点与群发功能后,在前端调用windows自带的消息通知,实现推送功能。

开发环境

  • Springboot 2.6.7
  • vue 2.6.11
  • socket-client 1.0.0

准备工作

在 Vue.js 项目中安装sockjs-client和stompjs。

npm install sockjs-client stompjs

在后端项目中添加依赖。

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

WebSocket

         为完成单播或者广播的频道的订阅功能,需要在前端和后端完成WebSocket的基本配置。

前端配置

        需在vue项目中新建websocket.js文件,主要完成:

        1.获取userid

        2.定义WebSocketService,完成connect、subscribe、unsubscribe、sendMessage、disconnect等主要函数。

代码如下所示。

websocket.js
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';

const userid = JSON.parse(sessionStorage.getItem('CurUser')).id

class WebSocketService {
    constructor() {
        this.stompClient = null;
        this.subscriptions = new Map(); // 存储订阅的频道
    }

    // 连接 WebSocket
    connect() {
        const socket = new SockJS("/api/broadcast"); // 后端地址
        this.stompClient = Stomp.over(socket);
        this.stompClient.connect({}, () => {
            console.log('do connect method');
            console.log('stompClient', this.stompClient)
            this.subscribe('/user/' + userid.toString() + '/alone/getResponse', (response) => {
                if (this.onGlobalNotification) {
                    console.log("message print", response)
                    // this.onGlobalNotification(JSON.parse(message.body));
                    this.onGlobalNotification(response.body);
                }
            });
        });
    }

    // 订阅频道
    subscribe(destination, callback) {
        const subscription = this.stompClient.subscribe(destination, callback);
        this.subscriptions.set(destination, subscription);
    }

    // 取消订阅
    unsubscribe(destination) {
        const subscription = this.subscriptions.get(destination);
        if (subscription) {
            subscription.unsubscribe();
            this.subscriptions.delete(destination);
        }
    }

    // 发送消息到后端
    sendMessage(destination, message) {
        console.log("sendMessage method , message is ", message.content)
        this.stompClient.send(destination, {}, message.content);
    }

    // 断开连接
    disconnect() {
        if (this.stompClient) {
            this.stompClient.disconnect();
            console.log('WebSocket 断开连接!');
        }
    }
}

export default new WebSocketService();

后端配置

        在后端同样需要完成频道的订阅,新建文件WebSocketConfig.java,代码如下所示。

package com.wms.common;

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;

import javax.annotation.Resource;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Resource
    public AppConfig appConfig;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker(
                "/user", "/topic1", "/topic2", "/mass"
        );
        // 点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是 /user/
        // 注意,这里必须和上面设置的Broker:/user 一致(两个都可以自定义,但必须一致)。否则连接不上
        registry.setUserDestinationPrefix("/user/");
        // 指服务端接收地址的前缀,意思就是说客户端给服务端发消息的地址的前缀
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 注册一个STOMP的endpoint端点,并指定使用SockJS协议
        // 前端使用这个地址连接后端 WebSocket接口
        registry.addEndpoint("/broadcast", "/point")
                // 允许所有源跨域。还可以指定ip配置:http://ip:*
                // 低版本的SpringBoot(2.1.5.RELEASE 就不行)不行
                .setAllowedOriginPatterns(appConfig.getFrontHttpUrl()) // 此处填写前端页面地址
                .withSockJS();
    }
}

Vue

        在用户登录之后,首先初始化WebSocket 连接,然后定义全局通知的回调,在回调函数onGlobalNotification中实现调用windows自带的通知功能Notification。

// 初始化 WebSocket 连接
WebSocketService.connect();
// 定义全局通知的回调
WebSocketService.onGlobalNotification = (message) => {
    this.sendNotification('xxx',message)
    // this.$bus.$emit("postTrigger")
};
    // 发送通知的方法
    sendNotification (title, body) {
      // console.log("sendNotification", Notification.permission)
      // 检查浏览器是否支持 Notification API
      if ('Notification' in window) {
        // 如果通知权限已经授予
        if (Notification.permission === "granted") {
          new Notification(title, {
            body: body,
            icon: logoIcon,
            requireInteraction: true
          });
        } else if (Notification.permission !== "denied") {
          // 请求用户授权
          Notification.requestPermission().then(permission => {
            if (permission === "granted") {
              new Notification(title, {
                body: body,
                icon: logoIcon,
                requireInteraction: true
              });
            }
          });
        }
      } else {
        console.log("浏览器不支持通知功能。");
      }
    },

        在需要发送消息的地方使用函数sendMessage,在MethodApi处填写后端对应接口。

WebSocketService.sendMessage(
    '/MethodApi', 
        {content: "message you want send"});

Springboot

        在后端需要在controller文件中实现对应的MethodApi接口函数, 确定消息传递的目标用户与对应的消息,调用messagingTemplate中的函数convertAndSendToUser,完成在频道/user/userid/alone/getResponse的消息通知。

controller.java
@Autowired
private SimpMessagingTemplate messagingTemplate;

// p2p notification
@MessageMapping("/MethodApi")
public void p2pNotify(String content){
	System.out.println(content);
	// 可在此处通过接受到的消息确定目标用户 userid(int) 与 对应的消息 message(string)
	System.out.println("=====发送通知=====");
	messagingTemplate.convertAndSendToUser(userid.toString(),"/alone/getResponse",message);
}

效果图

        此时就可以在本地进行测试了,效果如下:

服务器部署

        因为windows系统通知需要浏览器给予网页权限,所以需要vue启用https协议,配置如下:

module.exports = {
    devServer: {
        port:8001,
        https:true,
        proxy: {
            '/api': {
                target: "http://localhost:8091/", // 代理目标的基础路径
                secure: true,  // 如果是https接口,需要配置这个参数
                changeOrigin: true, // 支持跨域
                pathRewrite: {
                    '^/api': '',
                }
            }
        }
    },
}

文章转载自:
http://brakesman.lbooon.cn
http://anther.lbooon.cn
http://adoratory.lbooon.cn
http://bitter.lbooon.cn
http://agile.lbooon.cn
http://bosket.lbooon.cn
http://buddleia.lbooon.cn
http://bracer.lbooon.cn
http://aerenchyma.lbooon.cn
http://acetimeter.lbooon.cn
http://blowhard.lbooon.cn
http://calculable.lbooon.cn
http://chirography.lbooon.cn
http://alternant.lbooon.cn
http://balaton.lbooon.cn
http://brrr.lbooon.cn
http://bracteal.lbooon.cn
http://blivit.lbooon.cn
http://burnous.lbooon.cn
http://ailurophilia.lbooon.cn
http://aweather.lbooon.cn
http://apprehensively.lbooon.cn
http://asynchrony.lbooon.cn
http://anhematosis.lbooon.cn
http://ahmadabad.lbooon.cn
http://aigrette.lbooon.cn
http://bearberry.lbooon.cn
http://brachydactyl.lbooon.cn
http://captress.lbooon.cn
http://azathioprine.lbooon.cn
http://www.dtcms.com/a/111363.html

相关文章:

  • 接口自动化学习四:全量字段校验
  • L1-100 四项全能(测试点1)
  • 计算机网络知识点汇总与复习——(三)数据链路层
  • 在VMware下Hadoop分布式集群环境的配置--基于Yarn模式的一个Master节点、两个Slaver(Worker)节点的配置
  • Leetcode 33 -- 二分查找 | 归约思想
  • 【YOLO系列(V5-V12)通用数据集-交通红黄绿灯检测数据集】
  • SpringBoot集成swagger和jwt
  • Flask学习笔记 - 模板渲染
  • 深入探究 Hive 中的 MAP 类型:特点、创建与应用
  • 【Linux系统编程】进程概念,进程状态
  • 第三期:深入理解 Spring Web MVC [特殊字符](数据传参+ 特殊字符处理 + 编码问题解析)
  • 游戏编程模式学习(编程质量提升之路)
  • 25.4.4错题分析
  • Linux: network: 两台直连的主机业务不通
  • 【移动编程技术】作业1 中国现代信息科技发展史、Android 系统概述与程序结构 作业解析
  • Leetcode——150. 逆波兰表达式求值
  • 【小沐杂货铺】基于Three.JS绘制三维数字地球Earth(GIS 、three.js、WebGL、vue、react)
  • 平台总线---深入分析
  • transforms-pytorch4
  • 要素的选择与转出
  • 阿里云服务器遭遇DDoS攻击有争议?
  • 在MacOS 10.15上使用MongoDB
  • 洛谷题单3-P4956 [COCI 2017 2018 #6] Davor-python-流程图重构
  • linux signal up/down/down_interruptiable\down_uninterruptiable使用
  • 机器视觉工程师的专业精度决定职业高度,而专注密度决定成长速度。低质量的合群,不如高质量独处
  • linux 命令 awk
  • 洛谷题单3-P1217 [USACO1.5] 回文质数 Prime Palindromes-python-流程图重构
  • eBay新规倒计时:您的店铺配送方案即将被系统默认修改
  • python如何快速删除文件夹中的大量文件
  • 内网(域)渗透测试流程和模拟测试day--5--Windows和Linux的提权