vue中使用socket.io统计在线用户

目录

一、引入相关模块

[二、store/modules 中封装socketio](#二、store/modules 中封装socketio)

三、后端代码(nodejs)


一、引入相关模块

main.js 中参考以下代码 ,另外socketio的使用在查阅其它相关文章时有出入,还是尽量以官方文档为准

javascript 复制代码
import VueSocketIO from 'vue-socket.io'
import SocketIO from 'socket.io-client'

const SOCKETIO = new VueSocketIO({
  debug: true, // true开启
  connection: SocketIO('ws://127.0.0.1:8003',{
    autoConnect: false   //不自动连接
  }),
  options: {
    transports: ['websocket']
  },
  vuex: {
    store,
    actionPrefix: 'SOCKET_',
    mutationPrefix: 'SOCKET_'
  }
})

Vue.use(SOCKETIO)

二、store/modules 中封装socketio

代码如下:

javascript 复制代码
import io from 'socket.io-client';
import store from '../index';
import moment from 'moment';
let socket = {};
const state = {
    socket: {
        heartbeatActive: false,
        heartbeatInterval: null,
        heartbeatTimeout: null,
        reconnectAttempts: 0,
        maxReconnectAttempts: 5,
    },
}

const mutations = {
    START_HEARTBEAT(state) {
        state.heartbeatActive = true;
    },
    STOP_HEARTBEAT(state) {
        state.heartbeatActive = false;
    },
    SET_HEARTBEAT_INTERVAL(state, interval) {
        state.heartbeatInterval = interval;
    },
    SET_HEARTBEAT_TIMEOUT(state, timeout) {
        state.heartbeatTimeout = timeout;
    },
    INCREMENT_RECONNECT_ATTEMPTS(state) {
        state.reconnectAttempts += 1;
    },
    RESET_RECONNECT_ATTEMPTS(state) {
        state.reconnectAttempts = 0;
    }
}

const actions = {
    connectSocket({ commit, dispatch }) {
        socket=io('http://127.0.0.1:8003'); //socket 服务地址
        socket.connect();
        socket.on('connect', () => {
            console.log('Socket connected');
            dispatch('login');
            commit('START_HEARTBEAT');
            commit('RESET_RECONNECT_ATTEMPTS');
            dispatch('startHeartbeat');
        });
        socket.on('disconnect', () => {
            console.log('Socket disconnected');
            commit('STOP_HEARTBEAT');
            // dispatch('handleReconnect');
        });

        socket.on('pong', () => {
            console.log('Pong received');
            clearTimeout(this.state.heartbeatTimeout);
            dispatch('resetHeartbeatTimeout');
        });
    },
    login() {
        socket.emit('login',{ usercode: store.getters['name'],loginTime: moment().format('YYYY-MM-DD HH:mm:ss') });
    },
    disconnectSocket({ commit }) {
        socket.disconnect();
        clearInterval(state.heartbeatInterval);
        clearTimeout(state.heartbeatTimeout);
        commit('STOP_HEARTBEAT');
    },
    startHeartbeat({ commit, dispatch }) {
        const heartbeatInterval = setInterval(() => {
            console.log('user/usercode', store.getters['name'])
            //发送心跳包
            socket.emit('ping', { usercode: store.getters['name'],lastLoginTime: moment().format('YYYY-MM-DD HH:mm:ss') });
            dispatch('resetHeartbeatTimeout');
        }, 25000);
        commit('SET_HEARTBEAT_INTERVAL', heartbeatInterval);
    },
    resetHeartbeatTimeout({ commit, state, dispatch }) {
        if (state.heartbeatTimeout) {
            clearTimeout(state.heartbeatTimeout);
        }
        const heartbeatTimeout = setTimeout(() => {
            console.log('Heartbeat timeout, attempting to reconnect');
            dispatch('stopHeartbeat');
            dispatch('connectSocket');
        }, 30000); // 设置超时时间
        commit('SET_HEARTBEAT_TIMEOUT', heartbeatTimeout);
    },
    stopHeartbeat({ commit, state }) {
        clearInterval(state.heartbeatInterval);
        clearTimeout(state.heartbeatTimeout);
        commit('STOP_HEARTBEAT');
    },
    handleReconnect({ commit, state, dispatch }) {
        if (state.reconnectAttempts < state.maxReconnectAttempts) {
            commit('INCREMENT_RECONNECT_ATTEMPTS');
            setTimeout(() => {
                dispatch('connectSocket');
            }, 5000); // 重连间隔
        } else {
            console.log('Max reconnect attempts reached');
        }
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

触发事件写在了AppMain.vue中

javascript 复制代码
export default {
  name: 'AppMain',
  computed: {
    cachedViews() {
      return this.$store.state.tagsView.cachedViews
    },
    key() {
      return this.$route.fullPath
    }
  },
  mounted() {
    this.$store.dispatch('socketio/connectSocket'); //登陆成功后手动连接
    }
}

三、后端代码(nodejs)

单独封装了一个 socketio.js文件,这个根据个人喜好处理,简单样例代码

javascript 复制代码
global.socketClients= new Map();
global.io.on('connection', (socket) => {
    console.log('a user connected');
    
    socket.on('login', (data) => {
        console.log('login',data);
        global.socketClients.set(data.usercode,data);
        console.log(global.socketClients);
    });
    
    socket.on('ping', (data) => {
        console.log('received heartbeat');
        console.log('ping',data);
        if(global.socketClients.has(data.usercode)){
            global.socketClients.set(data.usercode,_.assign(global.socketClients.get(data.usercode),data));
        }else{
            global.socketClients.set(data.usercode,data);
        }
        console.log(global.socketClients);

    });

    socket.on('disconnect', (reason) => {
        if (reason === 'ping timeout') {
            console.log('Client disconnected due to heartbeat timeout');
        } else {
            console.log('Client disconnected due to:', reason);
        }
    });
});

相关数据可以用redis,或者放到表中进行一些其它逻辑的处理

附上后端示例:

前端列表:

相关推荐
weixin79893765432...2 小时前
Vue 渲染体系“三件套”(template 模板语法、h 函数和 JSX 语法)
vue.js·h函数·template 模板·jsx 语法
xkxnq2 小时前
第五阶段:Vue3核心深度深挖(第74天)(Vue3计算属性进阶)
前端·javascript·vue.js
Hilaku3 小时前
不要在简历上写精通 Vue3?来自面试官的真实劝退
前端·javascript·vue.js
竟未曾年少轻狂4 小时前
Vue3 生命周期钩子
前端·javascript·vue.js·前端框架·生命周期
TT哇4 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
用户982450514184 小时前
vue3响应式解构注意
vue.js
不会敲代码14 小时前
🚀 从DOM操作到Vue3:一个Todo应用的思维革命
vue.js
未来龙皇小蓝5 小时前
RBAC前端架构-02:集成Vue Router、Vuex和Axios实现基本认证实现
前端·vue.js·架构
晓得迷路了5 小时前
栗子前端技术周刊第 116 期 - 2025 JS 状态调查结果、Babel 7.29.0、Vue Router 5...
前端·javascript·vue.js
淡忘_cx6 小时前
使用Jenkins自动化部署vue项目(2.528.2版本)
vue.js·自动化·jenkins