YYPOST群发软件 发表于 4 天前

数据库MySQL用户在线状态管理心跳程序

数据库MySQL用户在线状态管理心跳程序



// 用户在线状态管理心跳程序
// 用于跟踪和管理用户在线状态的示例程序
//🍎交流QQ群711841924群一,苹果内测群,528816639
print.log("===== 用户在线状态管理心跳程序启动 =====");

// 全局变量
var conn = null;
var heartbeatInterval = null;
var isRunning = false;
var currentUser = null;

/**
* 连接数据库
*/
function connectDatabase() {
    try {
      var url = "jdbc:mysql://mysql2.sqlpub.com:3307/chaook";
      var user = "chaook";
      var password = "JAVsRUMHkoJ123xJ";
      var params = "?useSSL=false&characterEncoding=utf8";
      
      print.log("正在连接数据库...");
      conn = mysql.getConnection(url, user, password);
      print.log("✅ 数据库连接成功");
      return true;
    } catch (e) {
      print.log("❌ 数据库连接失败: " + e.message);
      return false;
    }
}

/**
* 初始化数据库表结构
*/
function initializeDatabase() {
    try {
      // 创建用户在线状态表
      var userTableSql = "CREATE TABLE IF NOT EXISTS 用户在线状态表 (" +
                        "用户ID VARCHAR(50) PRIMARY KEY," +
                        "用户名 VARCHAR(100)," +
                        "在线状态 TINYINT DEFAULT 0," +// 0-离线, 1-在线
                        "最后活跃时间 DATETIME," +
                        "会话开始时间 DATETIME," +
                        "在线时长 INT DEFAULT 0" +       // 单位:秒
                        ") ENGINE=InnoDB DEFAULT CHARSET=utf8";
                           
      var stmt = conn.createStatement();
      stmt.executeUpdate(userTableSql);
      stmt.close();
      
      // 创建用户活动日志表
      var logTableSql = "CREATE TABLE IF NOT EXISTS 用户活动日志表 (" +
                         "日志ID INT AUTO_INCREMENT PRIMARY KEY," +
                         "用户ID VARCHAR(50)," +
                         "活动类型 VARCHAR(50)," +
                         "活动详情 TEXT," +
                         "活动时间 DATETIME DEFAULT CURRENT_TIMESTAMP," +
                         "FOREIGN KEY (用户ID) REFERENCES 用户在线状态表(用户ID) ON DELETE CASCADE" +
                         ") ENGINE=InnoDB DEFAULT CHARSET=utf8";
                        
      stmt = conn.createStatement();
      stmt.executeUpdate(logTableSql);
      stmt.close();
      
      print.log("✅ 数据库表结构初始化完成");
      return true;
    } catch (e) {
      print.log("❌ 数据库表结构初始化失败: " + e.message);
      return false;
    }
}

/**
* 用户登录
*/
function userLogin(userId, username) {
    try {
      var sql = "INSERT INTO 用户在线状态表 (用户ID, 用户名, 在线状态, 最后活跃时间, 会话开始时间) " +
                  "VALUES (?, ?, 1, NOW(), NOW()) " +
                  "ON DUPLICATE KEY UPDATE 用户名 = VALUES(用户名), 在线状态 = 1, 最后活跃时间 = NOW(), 会话开始时间 = NOW()";
                  
      var pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, userId);
      pstmt.setString(2, username);
      pstmt.executeUpdate();
      pstmt.close();
      
      logUserActivity(userId, "用户登录", "用户 " + username + " 登录系统");
      currentUser = {id: userId, name: username};
      print.log("✅ 用户 " + username + " 登录成功");
      return true;
    } catch (e) {
      print.log("❌ 用户登录失败: " + e.message);
      return false;
    }
}

/**
* 发送用户心跳包
*/
function sendUserHeartbeat(userId) {
    try {
      var sql = "UPDATE 用户在线状态表 SET 在线状态 = 1, 最后活跃时间 = NOW() WHERE 用户ID = ?";
                  
      var pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, userId);
      pstmt.executeUpdate();
      pstmt.close();
      
      logUserActivity(userId, "心跳包", "发送心跳包,更新用户活跃时间");
      print.log("✅ 用户 " + userId + " 心跳包发送成功");
      return true;
    } catch (e) {
      print.log("❌ 心跳包发送失败: " + e.message);
      return false;
    }
}

/**
* 记录用户活动日志
*/
function logUserActivity(userId, activityType, details) {
    try {
      var sql = "INSERT INTO 用户活动日志表 (用户ID, 活动类型, 活动详情) VALUES (?, ?, ?)";
      var pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, userId);
      pstmt.setString(2, activityType);
      pstmt.setString(3, details);
      pstmt.executeUpdate();
      pstmt.close();
      return true;
    } catch (e) {
      // 日志记录失败不影响主流程
      print.log("⚠️ 用户活动日志记录失败: " + e.message);
      return false;
    }
}

/**
* 检查用户在线状态
*/
function checkUserStatus() {
    try {
      var sql = "SELECT 用户ID, 用户名, 在线状态, 最后活跃时间, 会话开始时间 FROM 用户在线状态表";
      var stmt = conn.createStatement();
      var rs = stmt.executeQuery(sql);
      
      print.log("\n=== 用户在线状态监控 ===");
      print.log("用户ID\t\t用户名\t\t在线状态\t最后活跃时间\t\t\t会话开始时间");
      print.log("-----------------------------------------------------------------------------------------------");
      
      var offlineUsers = [];
      var onlineUsers = [];
      
      while (rs.next()) {
            var userId = rs.getString("用户ID");
            var username = rs.getString("用户名");
            var onlineStatus = rs.getInt("在线状态");
            var lastActive = rs.getTimestamp("最后活跃时间");
            var sessionStart = rs.getTimestamp("会话开始时间");
            
            // 格式化输出
            var nameStr = username + "\t\t";
            if (username.length >= 4) nameStr = username + "\t";
            
            var statusStr = onlineStatus === 1 ? "在线" : "离线";
            
            print.log(userId + "\t" + nameStr + statusStr + "\t\t" + lastActive + "\t" + sessionStart);
            
            // 分类用户
            if (onlineStatus === 1) {
                onlineUsers.push({id: userId, name: username, lastActive: lastActive});
            } else {
                offlineUsers.push({id: userId, name: username});
            }
      }
      
      rs.close();
      stmt.close();
      
      // 报告统计信息
      print.log("\n📊 统计信息:");
      print.log("在线用户数: " + onlineUsers.length);
      print.log("离线用户数: " + offlineUsers.length);
      
      if (onlineUsers.length > 0) {
            print.log("\n🟢 在线用户列表:");
            for (var i = 0; i < onlineUsers.length; i++) {
                var user = onlineUsers;
                print.log("- " + user.name + " (" + user.id + ") 最后活跃: " + user.lastActive);
            }
      }
      
      if (offlineUsers.length > 0) {
            print.log("\n&#128308; 离线用户列表:");
            for (var i = 0; i < offlineUsers.length; i++) {
                var user = offlineUsers;
                print.log("- " + user.name + " (" + user.id + ")");
            }
      }
      
      print.log("");
      return true;
    } catch (e) {
      print.log("❌ 用户状态检查失败: " + e.message);
      return false;
    }
}

/**
* 用户登出
*/
function userLogout(userId) {
    try {
      // 更新在线时长
      var durationSql = "UPDATE 用户在线状态表 SET 在线时长 = TIMESTAMPDIFF(SECOND, 会话开始时间, NOW()) WHERE 用户ID = ?";
      var pstmt = conn.prepareStatement(durationSql);
      pstmt.setString(1, userId);
      pstmt.executeUpdate();
      pstmt.close();
      
      // 设置为离线状态
      var sql = "UPDATE 用户在线状态表 SET 在线状态 = 0 WHERE 用户ID = ?";
      pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, userId);
      pstmt.executeUpdate();
      pstmt.close();
      
      logUserActivity(userId, "用户登出", "用户登出系统");
      print.log("✅ 用户 " + userId + " 登出成功");
      return true;
    } catch (e) {
      print.log("❌ 用户登出失败: " + e.message);
      return false;
    }
}

/**
* 心跳任务执行函数
*/
function executeHeartbeatTask() {
    print.log("\n⏰ 执行用户心跳任务 - " + new Date());
   
    try {
      // 检查数据库连接
      if (!conn || conn.isClosed()) {
            print.log("⚠️ 数据库连接已断开,尝试重新连接...");
            if (!connectDatabase()) {
                print.log("❌ 无法重新连接数据库,跳过本次心跳任务");
                return;
            }
      }
      
      // 如果有当前用户,发送心跳包
      if (currentUser) {
            sendUserHeartbeat(currentUser.id);
      }
      
      // 检查所有用户状态
      checkUserStatus();
      
      print.log("✅ 用户心跳任务执行完成\n");
    } catch (e) {
      print.log("❌ 用户心跳任务执行失败: " + e.message);
    }
}

/**
* 启动心跳服务
*/
function startHeartbeatService(intervalSeconds) {
    if (isRunning) {
      print.log("⚠️ 心跳服务已经在运行中");
      return false;
    }
   
    // 连接数据库
    if (!connectDatabase()) {
      print.log("❌ 无法启动心跳服务:数据库连接失败");
      return false;
    }
   
    // 初始化数据库
    if (!initializeDatabase()) {
      print.log("❌ 无法启动心跳服务:数据库初始化失败");
      return false;
    }
   
    isRunning = true;
    print.log("✅ 心跳服务启动成功,间隔: " + intervalSeconds + "秒");
   
    // 立即执行一次
    executeHeartbeatTask();
   
    // 设置定时任务
    heartbeatInterval = setInterval(function() {
      executeHeartbeatTask();
    }, intervalSeconds * 1000);
   
    return true;
}

/**
* 停止心跳服务
*/
function stopHeartbeatService() {
    if (!isRunning) {
      print.log("⚠️ 心跳服务未在运行");
      return false;
    }
   
    if (heartbeatInterval) {
      clearInterval(heartbeatInterval);
      heartbeatInterval = null;
    }
   
    isRunning = false;
    print.log("✅ 心跳服务已停止");
    return true;
}

/**
* 关闭数据库连接
*/
function closeConnection() {
    try {
      if (conn != null) {
            conn.close();
      }
      print.log("✅ 数据库连接已关闭");
    } catch (e) {
      print.log("❌ 关闭连接时出错: " + e.message);
    }
}

/**
* 程序退出处理
*/
function exitHandler() {
    print.log("正在关闭心跳服务...");
    // 如果有用户登录,执行登出操作
    if (currentUser) {
      userLogout(currentUser.id);
    }
    stopHeartbeatService();
    closeConnection();
    print.log("&#128075; 用户在线状态管理心跳程序已退出");
}

// 主程序
try {
    print.log("&#128640; 启动用户在线状态管理心跳程序");
   
    // 注册退出处理函数
    java.lang.Runtime.getRuntime().addShutdownHook(new java.lang.Thread({
      run: function() {
            exitHandler();
      }
    }));
   
    // 启动心跳服务 (每30秒执行一次)
    if (startHeartbeatService(30)) {
      print.log("✅ 用户在线状态管理心跳程序已启动");
      print.log("&#128161; 按 Ctrl+C 停止程序");
      
      // 模拟用户登录
      print.log("&#128221; 模拟用户登录...");
      userLogin("USER_001", "张三");
      
      // 保持程序运行
      while (isRunning) {
            java.lang.Thread.sleep(1000);
      }
    } else {
      print.log("❌ 用户在线状态管理心跳程序启动失败");
    }
   
} catch (e) {
    print.log("❌ 程序执行过程中发生错误: " + e.message);
    exitHandler();
}

print.log("===== 用户在线状态管理心跳程序结束 =====");

页: [1]
查看完整版本: 数据库MySQL用户在线状态管理心跳程序