• vue中使用 websoket


    原文地址:https://blog.csdn.net/qq_29918313/article/details/85059364

    Vuex 注入 Vue 生命周期的过程:https://mp.weixin.qq.com/s/WnRMCArDMy-PiFLprmMmCg

    一、首先,想谈一下什么时候使用vuex:

    (1)如果数据还有其他组件复用,建议放在vuex,比如在我所实现的项目中,实现了在线聊天功能,其中的对话框是有多个组件实现,而用户名等相关信息在各个组件中都需要使用;

    (2)如果需要跨多级组件传递数据,建议放在vuex;

    (3)需要持久化的数据(如登录后用户的信息),建议放在vuex,同样在我所实现的项目中,登录后用户的信息是放在了vuex中,需要使用的地方直接调用;

    (4)跟当前业务组件强相关的数据,可以放在组件内;

    以下文章更加详细的描述了什么场景下及为什么使用vuex:https://juejin.im/post/5b8e4b40f265da437174cbfe

    vuex和浏览器缓存:https://segmentfault.com/q/1010000014557487

    首先,要区别 vuex 和 浏览器缓存 的区别。

    vuex 的设计是将数据存在一个对象树的变量中,我们的应用(vue应用)从这个变量中取数据,然后供应用使用,当将当前页面关闭, vuex 中的变量会随着消失,重新打开页面的时候,需要重新生成。
    
    而,浏览器缓存(cookie,localstorage等)是将数据存到浏览器的某个地方,关闭页面,不会自动清空这些数据,当再次打开这个页面时,还是能取到之前存在浏览器上的数据(cookie,localstorage等)。
    
    要使用 vuex 还是使用浏览器缓存,要看具体的业务场景。比如:像用户校验的 token 就可以存在 cookie 中,因为用户再次登录的时候能用到。而像用户的权限数据,这些是有一定安全性考虑,且不同用户的权限不同,放在 vuex 中更合理,用户退出时,自动销毁。

    其次,vuex 中的 state 是单向的,也可以异步操作,这两个没有冲突。

    vuex 中的 state 的设计思路是保证数据的一致性和连续性,而让 state 中的值只能通过 action 来发起 commit,进而改变 state 中的值。
    而,action 中是 同步 还是 异步,都是单向地改变 state 中的值。

    二、接下来讲vuex是什么?

    该介绍来自官网:https://vuex.vuejs.org/zh/

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

    •  每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
    • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
    • 通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。

    三、从项目出发

    原文

    vue使用SockJS实现webSocket通信

    以前使用websocket都是使用

    window.webSocket = new WebSocket('ws://' + config.webSocketUrl + '/webData/websocket?token=' + token + '&username=' + username);
    这种方式进行操作。由于项目要求,需要访问网关因此需要使用http的连接方式进行socket信息推送,以下用的是 SockJS。

    # 2020-02-19更新
    在项目前期开发,我们都是在全局的js文件中定义socket的连接ip和端口,在页面调用。但在项目优化过程中,我们希望可以直接使用webpack的代理模式,直接通过代码进行请求,这样页面就不需要进行socket地址的配置。
    优点:(1)页面减少全量变量的配置;(2)系统方法调用的统一性,和其他普通的接口调用代理一致。
    缺点:(1)由于在页面中配置的代理,而不是直接请求http:xxxx,导致需要在代理服务器中(例如ngnix)上多添加一个代理配置。相当于把以前http的直接请求方式变成代理转发请求。
    具体更改模式为:
      1、在自定义的websocket.js文件中,创建SockJS对象:
    新写法:const socket = new SockJS('/bullet');// 连接SockJS的endpoint名称为"bullet"
        旧写法:let socket = new SockJS('http://'+config.webSocketUrl+'/bullet');//连接SockJS的endpoint名称为"bullet"
      2、在项目根目录下的config/index.js文件中(vue-cli2.0),或者vue.config.js(vue-cli3.0)添加代理配置即可。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    proxyTable: {
      '/bullet': {
        target: target,  //target为目标变量
        ws: true,
        pathRewrite: {
          '^/bullet''/bullet'
        },
      }
    },

        

     

    2019-04-11更新
    随着项目的模块化,需要把websocket相关的功能独自创建一个模块进行引入使用,以下是本人的操作方式:
    1.在utils目录下创建一个js文件,可以命名为:websocket.js


    2.在websocket.js文件中写入相关的socket.io代码
    说明:config.webSocketUrl是一个url地址的变量。主要是在vue项目中的static文件夹下创建一个js文件(不会被webpack压缩),定义全局常量、变量,并在index.html中做为一个原生的js文件使用<script>标签引入即可。在项目部署过程中,直接修改js文件,即可对相应的数据进行更改。
    复制代码
    // socket功能
    import SockJS from "sockjs-client";
    import Stomp from "stompjs";
    import store from "../store";
    
    export function connectionSocket() {
      let socket = new SockJS('http://'+config.webSocketUrl+'/bullet');//连接SockJS的endpoint名称为"bullet"
      console.log('socket连接地址:'+'http://'+config.webSocketUrl+'/bullet');
      // 获取STOMP子协议的客户端对象
      let stompClient = Stomp.over(socket);
      // 定义客户端的认证信息,按需求配置
      let headers = {
        Authorization:store.getters.token
      };
    
      // 拦截输出的一大堆垃圾信息
      stompClient.debug = function (str) {
        $("#debug").append(str + "
    ");
      };
      // 向服务器发起websocket连接
      stompClient.connect(headers,() => {
        stompClient.subscribe('/topic/getResponse', (response) => { // 订阅服务端提供的某个topic
          if (response.body) {
            const repObj = JSON.parse(response.body);
            if (repObj.data.webSocketType == 'ISEVehicle') { //监控管理,新版车辆监控
              if (repObj.status == 200) {
                store.dispatch('carMonitorFun', repObj);
              }  else if (repObj.data.webSocketType == 'vehicleAlarm') { //智感安防首页,车辆告警数据推送
              if (repObj.status == 200) {
                store.commit('vehicleAlarmMUTA', repObj.data);
              }
            }
          }
        });
        stompClient.subscribe('/user/'+store.getters.userRegionCode+'/queue/getResponse', (response) => { // 订阅服务端提供的某个topic
          if (response.body) {
            const repObj = JSON.parse(response.body);
             if (repObj.data.webSocketType == 'personAlarm') { //智感安防首页,人脸预警数据推送
              if (repObj.status == 200) {
                store.commit('personAlarmMUTA', repObj.data);
              }
            }
            else if (repObj.data.webSocketType == 'vehicleAlarm') { //智感安防首页,车辆告警数据推送
              if (repObj.status == 200) {
                store.commit('vehicleAlarmMUTA', repObj.data);
              }
            }
          }
        });
        stompClient.subscribe('/user/'+store.getters.token+'/queue/getResponse', (response) => { // 订阅服务端提供的某个topic
          if (response.body) {
            let repObj = JSON.parse(response.body);
            if (repObj.data.webSocketType =='task') { store.commit('monitorStatus', repObj);} //任务列表//当监控到websocket有数据返回的时候,修改monitorStatus使其发生变化即可
            else if (repObj.data.webSocketType == 'networkConfig') { store.commit('monitorStatusMUTA', repObj);}//联网配置
           
          }
        });
      }, (err) => {
        // 连接发生错误时的处理函数
        console.log('失败')
      });
    }
    复制代码

      3.在页面需要初始化的地方因为该js文件即可

     

     


    2018-12-13创建
    先安装 sockjs-client 和 stompjs 
    1
    2
    npm install sockjs-client
    npm install stompjs  
    复制代码
    import SockJS from  'sockjs-client';
    import  Stomp from 'stompjs';
    export default {
        data(){
            return {
                stompClient:'',
                timer:'',
            }
        },
        methods:{
            initWebSocket() {
                this.connection();
                let that= this;
                // 断开重连机制,尝试发送消息,捕获异常发生时重连
                this.timer = setInterval(() => {
                    try {
                        that.stompClient.send("test");
                    } catch (err) {
                        console.log("断线了: " + err);
                        that.connection();
                    }
                }, 5000);
            },  
            connection() {
                // 建立连接对象
                let socket = new SockJS('http://10.10.91.4:8081/ws');
                // 获取STOMP子协议的客户端对象
                this.stompClient = Stomp.over(socket);
                // 定义客户端的认证信息,按需求配置
                let headers = {
                    Authorization:''
                }
                // 向服务器发起websocket连接
                this.stompClient.connect(headers,() => {
                    this.stompClient.subscribe('/topic/public', (msg) => { // 订阅服务端提供的某个topic
                        console.log('广播成功')
                        console.log(msg);  // msg.body存放的是服务端发送给我们的信息
                    },headers);
                    this.stompClient.send("/app/chat.addUser",
                        headers,
                        JSON.stringify({sender: '',chatType: 'JOIN'}),
                    )   //用户加入接口
                }, (err) => {
                    // 连接发生错误时的处理函数
                    console.log('失败')
                    console.log(err);
                });
            },    //连接 后台
            disconnect() {
                if (this.stompClient) {
                    this.stompClient.disconnect();
                }
            },  // 断开连接
        },
        mounted(){
            this.initWebSocket();
        },
        beforeDestroy: function () {
            // 页面离开时断开连接,清除定时器
            this.disconnect();
            clearInterval(this.timer);
        }
    }
     
    复制代码
    问题
    安装 sockjs-client、stompjs;在这儿要注意一下,我在"stompjs": "^2.3.3"这个版本发现,引入stompjs会报一个net模块找不到,需要在stompjs模块根目录下执行npm install net,这个是个奇葩的问题

    进入到module目录下的stompjs目录,执行npm install net

     

     

    使用vuex全局封装方法(以连接websocket,调用websocket方法为例)

  • 相关阅读:
    spring boot 2 上传文件大小限制的配置不生效解决方式
    jsr基本使用@valid和@validation
    C#基础拾遗系列之一:先看懂IL代码
    ideal key
    dotnet watch+vs code提升asp.net core开发效率
    Mybatis使用
    java webservice
    JavaScript ES6 规范
    Express (Routing、Middleware、托管静态文件、view engine 等等)
    mongoDB (mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
  • 原文地址:https://www.cnblogs.com/mmzuo-798/p/13031923.html
Copyright © 2020-2023  润新知