uniapp 封装socket


utils/socket.js

import config from '@/config'
import store from '@/store'
import {updateUrl} from '@/config'
class socketIO {
    constructor() {
        this.socketTask = null
        this.is_open_socket = false //避免重复连接
        this.is_show_Loading  = false
        // 为空就为1 admin
        this.url = store.state.baseUrl.socketUrl + (store.state.user.userinfo.personId || '1') //连接地址
        this.connectNum = 1 // 重连次数
        this.followFlake = true // traderDetailIndex == true 重连
        //心跳检测
        this.timeout = 15000 //多少秒执行检测
        this.heartbeatInterval = null //
        this.reconnectTimeOut = null //
    }
 
    // 进入这个页面的时候创建websocket连接【整个页面随时使用】
    connectSocketInit() {
        this.socketTask = uni.connectSocket({
            url: this.url,
            success: () => {
                // 返回实例
                return this.socketTask
            },
            fail:(err)=>{
                console.log(err)
            }
        });
        this.socketTask.onOpen((res) => {
            if(this.connectNum > 1) store.commit('SET_BASEURL','inIp')
            console.log('连接成功');
            this.connectNum = 1
            clearInterval(this.reconnectTimeOut)
            clearInterval(this.heartbeatInterval)
            this.is_open_socket = true;
            // this.is_show_Loading = true;
            uni.hideLoading()
            this.start();
            // 注:只有连接正常打开中 ,才能正常收到消息
            this.socketTask?.onMessage((res) => {
                // 字符串转json
                const {data} = res
                const index = data.indexOf('alarm')
                if(index > -1 ){
                    const arr = JSON.parse(data.slice(data.indexOf('[')))
                    uni.$emit('socket', arr[1])
                }
            });
        })
        // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
        uni.onSocketError((res) => {
            store.commit('SET_BASEURL','outIp')
            console.log('WebSocket连接打开失败,请检查!', this.connectNum);
            // if(this.is_show_Loading){
            //     uni.showLoading({
            //         title: `正在尝试重连`,
            //         mask: true
            //     })
            // }
            this.socketTask = null
            this.is_open_socket = false;
            // this.is_show_Loading = false;
            clearInterval(this.heartbeatInterval)
            clearInterval(this.reconnectTimeOut)
            // uni.$off('getPositonsOrder')
            // if (this.connectNum < 6000) {
            
            this.reconnect();
            this.connectNum += 1
            // } else {
            // uni.$emit('connectError');
            // this.connectNum = 1
            // }
 
        });
 
        // 这里仅是事件监听【如果socket关闭了会执行】
        this.socketTask.onClose(() => {
            console.log("已经被关闭了-------")
            clearInterval(this.heartbeatInterval)
            clearInterval(this.reconnectTimeOut)
            this.is_open_socket = false;
            // this.is_show_Loading = false;
            this.socketTask = null
            // uni.$off('getPositonsOrder')
            if (this.connectNum < 6) {
                // this.reconnect();
            } else {
                uni.$emit('connectError');
                this.connectNum = 1
            }
 
        })
    }
    // 主动关闭socket连接
    Close() {
        if (!this.is_open_socket) {
            return
        }
        this.socketTask.close({
            
        });
    }
    //发送消息
    send(data) {
        // console.log("data---------->", data);
        // 注:只有连接正常打开中 ,才能正常成功发送消息
        if (this.socketTask) {
            this.socketTask.send({
                data: '',
                async success() {
                    // console.log("消息发送成功");
                },
            });
        }
    }
    //开启心跳检测
    start() {
        this.heartbeatInterval = setInterval(() => {
            this.send('');
        }, this.timeout)
    }
 
 
    //重新连接
    reconnect() {
        //停止发送心跳
        clearInterval(this.heartbeatInterval)
        //如果不是人为关闭的话,进行重连
        if (!this.is_open_socket && this.followFlake) {
            this.reconnectTimeOut = setInterval(() => {
                this.connectSocketInit(this.data);
            }, 3000)
        }
    }
 
}
module.exports = socketIO

 

 

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/store/modules/user'
import setting from '@/store/modules/setting'
import app from '@/store/modules/app'
import baseUrl from '@/store/modules/baseUrl'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    user,
    app,
    setting,
    baseUrl
  },
  getters
})

export default store

store/modules/user.js

import config from '@/config'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { login, logout, getInfo, loginByUuid,getRouters } from '@/api/login'
import { getToken, setToken, removeToken, getImei, setImei, removeImei } from '@/utils/auth'
import {encrypt} from '@/utils/jsencrypt.js'
import {todoList} from "@/api/todo";
import {getTotalTodo} from "@/api/isolated/index.js"
import socketIO from '@/utils/socket.js'
import route from '../../uni_modules/uview-ui/libs/util/route'

const baseUrl = config.baseUrl

const user = {
  state: {
    token: getToken(),
    name: storage.get(constant.name),
    avatar: storage.get(constant.avatar),
    roles: storage.get(constant.roles),
    permissions: storage.get(constant.permissions),
    userinfo: uni.getStorageSync('userinfo'),
    todo: 0,//待办
    todoTimer: null,//待办定时器
    socket:null,
    isloated_todo: 0, // 能量隔离处理数据
    route:uni.getStorageSync('route')
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_NAME: (state, name) => {
      state.name = name
      storage.set(constant.name, name)
    },
    SET_AVATAR: (state, avatar) => {
      state.avatar = avatar
      storage.set(constant.avatar, avatar)
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles
      storage.set(constant.roles, roles)
    },
    SET_PERMISSIONS: (state, permissions) => {
      state.permissions = permissions
      storage.set(constant.permissions, permissions)
    },
    SET_USERINFO: (state, userinfo) => {
      state.userinfo = userinfo
      uni.setStorageSync('userinfo',userinfo)
    },
    SET_TODO: (state, todo) => {
        state.todo = todo
    },
    SET_TODOTIMER: (state, time) => {
        state.todoTimer = time
    },
    SET_SOCKET: (state, data)=>{
        state.socket = data
    },
    SET_ROUTE: (state, data)=>{
        state.route = data
        uni.setStorageSync('route',data)
    },
    SET_ISOLATED_TODO:(state, todo)=>{
        state.isloated_todo = todo
    }
  },

  actions: {
    // 登录
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      const password = encrypt(userInfo.password)
      const code = userInfo.code
      const uuid = userInfo.uuid
      const iemi = userInfo.iemi
      return new Promise((resolve, reject) => {
        login(username, password, code, uuid, iemi).then(res => {
            if(res.data.strength){
                setToken(res.data.token)
                commit('SET_TOKEN', res.data.token)
                resolve()
            }else{
                resolve(res.data.token)
            }
        }).catch(error => {
          reject(error)
        })
      })
    },
    
    // imei登录
    loginImei({commit}, imei){
        return new Promise((resolve, reject) => {
          loginByUuid({iemi:imei}).then(res => {
              if(res.data?.token){
                  setToken(res.data.token)
                  commit('SET_TOKEN', res.data.token)
                  resolve()
              }else{
                  removeToken()
                  removeImei()
                  reject()
              }
          }).catch(error => {
              removeToken()
              removeImei()
            reject(error)
          })
        })
    },
    
    // 获取用户信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo().then(res => {
          const user = res.data.user
          const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : user.avatar
          const username = (user == null || user.nickName == "" || user.nickName == null) ? "" : user.nickName
          if (res.data.roles && res.data.roles.length > 0) {
            commit('SET_ROLES', res.data.roles)
            commit('SET_PERMISSIONS', res.data.permissions)
          } else {
            commit('SET_ROLES', ['ROLE_DEFAULT'])
          }
          commit('SET_NAME', username)
          commit('SET_AVATAR', avatar)
          commit('SET_USERINFO',user)
          commit('SET_SOCKET',new socketIO())
          state.socket.connectSocketInit()
          getRouters({terminalType:2}).then(route=>{
              commit('SET_ROUTE',route.data);
          })
          resolve(res);
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 退出系统
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout(state.token).then(() => {
          clearInterval(state.todoTimer)
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          commit('SET_PERMISSIONS', [])
          commit('SET_TODOTIMER', null)
          commit('SET_USERINFO',{})
          commit('SET_ISOLATED_TODO', 0)
          removeToken()
          storage.clean()
          state.socket?.Close()
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },
    // 前端 登出
    FedLogOut({ commit,state }) {
      return new Promise(resolve => {
        clearInterval(state.todoTimer)
        commit('SET_TOKEN', '')
        commit('SET_ROLES', [])
        commit('SET_PERMISSIONS', [])
        commit('SET_TODOTIMER', null)
        commit('SET_USERINFO',{})
        commit('SET_ISOLATED_TODO', 0)
        removeToken()
        storage.clean()
        state.socket?.Close()
        resolve()
      })
    },
    // 待办定时器
    setIntervalTodo({dispatch,commit,state}){
        if(state.todoTimer) return
        dispatch('GetTodoList')
        commit('SET_TODOTIMER',setInterval(() => {
          dispatch('GetTodoList')
        }, 1000 * 20))
    },
    // 待办
    GetTodoList({commit}){
      todoList({pageNum: 1,pageSize: 1,}).then(res=>{
        if(res.data) commit('SET_TODO',res.data.total)
      })
    },
    
    // 能量隔离统计角标
    getTotalTodo({commit}){
        getTotalTodo().then(res=>{
            commit('SET_ISOLATED_TODO',res.data)
        })
    }
  }
}

export default user

utils/auth.js

const TokenKey = 'App-Token'
// MD5唯一标识
const Imei = 'imei'

export function getToken() {
  return uni.getStorageSync(TokenKey)
}

export function setToken(token) {
  return uni.setStorageSync(TokenKey, token)
}

export function removeToken() {
  return uni.removeStorageSync(TokenKey)
}

export function getImei() {
  return uni.getStorageSync(Imei)
}

export function setImei(imei) {
  return uni.setStorageSync(Imei, imei)
}

export function removeImei() {
  return uni.removeStorageSync(Imei)
}

 

posted on 2024-06-27 14:38  小虾米吖~  阅读(29)  评论(0编辑  收藏  举报