B2B网络软件

标题: 数据库MySQL用户在线状态管理心跳程序 [打印本页]

作者: YYPOST群发软件    时间: 9 小时前
标题: 数据库MySQL用户在线状态管理心跳程序
数据库MySQL用户在线状态管理心跳程序
数据库MySQL用户在线状态管理心跳程序 B2B网络软件
数据库MySQL用户在线状态管理心跳程序 B2B网络软件

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

  5. // 全局变量
  6. var conn = null;
  7. var heartbeatInterval = null;
  8. var isRunning = false;
  9. var currentUser = null;

  10. /**
  11. * 连接数据库
  12. */
  13. function connectDatabase() {
  14.     try {
  15.         var url = "jdbc:mysql://mysql2.sqlpub.com:3307/chaook";
  16.         var user = "chaook";
  17.         var password = "JAVsRUMHkoJ123xJ";
  18.         var params = "?useSSL=false&characterEncoding=utf8";
  19.         
  20.         print.log("正在连接数据库...");
  21.         conn = mysql.getConnection(url, user, password);
  22.         print.log("✅ 数据库连接成功");
  23.         return true;
  24.     } catch (e) {
  25.         print.log("❌ 数据库连接失败: " + e.message);
  26.         return false;
  27.     }
  28. }

  29. /**
  30. * 初始化数据库表结构
  31. */
  32. function initializeDatabase() {
  33.     try {
  34.         // 创建用户在线状态表
  35.         var userTableSql = "CREATE TABLE IF NOT EXISTS 用户在线状态表 (" +
  36.                           "用户ID VARCHAR(50) PRIMARY KEY," +
  37.                           "用户名 VARCHAR(100)," +
  38.                           "在线状态 TINYINT DEFAULT 0," +  // 0-离线, 1-在线
  39.                           "最后活跃时间 DATETIME," +
  40.                           "会话开始时间 DATETIME," +
  41.                           "在线时长 INT DEFAULT 0" +       // 单位:秒
  42.                           ") ENGINE=InnoDB DEFAULT CHARSET=utf8";
  43.                            
  44.         var stmt = conn.createStatement();
  45.         stmt.executeUpdate(userTableSql);
  46.         stmt.close();
  47.         
  48.         // 创建用户活动日志表
  49.         var logTableSql = "CREATE TABLE IF NOT EXISTS 用户活动日志表 (" +
  50.                          "日志ID INT AUTO_INCREMENT PRIMARY KEY," +
  51.                          "用户ID VARCHAR(50)," +
  52.                          "活动类型 VARCHAR(50)," +
  53.                          "活动详情 TEXT," +
  54.                          "活动时间 DATETIME DEFAULT CURRENT_TIMESTAMP," +
  55.                          "FOREIGN KEY (用户ID) REFERENCES 用户在线状态表(用户ID) ON DELETE CASCADE" +
  56.                          ") ENGINE=InnoDB DEFAULT CHARSET=utf8";
  57.                         
  58.         stmt = conn.createStatement();
  59.         stmt.executeUpdate(logTableSql);
  60.         stmt.close();
  61.         
  62.         print.log("✅ 数据库表结构初始化完成");
  63.         return true;
  64.     } catch (e) {
  65.         print.log("❌ 数据库表结构初始化失败: " + e.message);
  66.         return false;
  67.     }
  68. }

  69. /**
  70. * 用户登录
  71. */
  72. function userLogin(userId, username) {
  73.     try {
  74.         var sql = "INSERT INTO 用户在线状态表 (用户ID, 用户名, 在线状态, 最后活跃时间, 会话开始时间) " +
  75.                   "VALUES (?, ?, 1, NOW(), NOW()) " +
  76.                   "ON DUPLICATE KEY UPDATE 用户名 = VALUES(用户名), 在线状态 = 1, 最后活跃时间 = NOW(), 会话开始时间 = NOW()";
  77.                   
  78.         var pstmt = conn.prepareStatement(sql);
  79.         pstmt.setString(1, userId);
  80.         pstmt.setString(2, username);
  81.         pstmt.executeUpdate();
  82.         pstmt.close();
  83.         
  84.         logUserActivity(userId, "用户登录", "用户 " + username + " 登录系统");
  85.         currentUser = {id: userId, name: username};
  86.         print.log("✅ 用户 " + username + " 登录成功");
  87.         return true;
  88.     } catch (e) {
  89.         print.log("❌ 用户登录失败: " + e.message);
  90.         return false;
  91.     }
  92. }

  93. /**
  94. * 发送用户心跳包
  95. */
  96. function sendUserHeartbeat(userId) {
  97.     try {
  98.         var sql = "UPDATE 用户在线状态表 SET 在线状态 = 1, 最后活跃时间 = NOW() WHERE 用户ID = ?";
  99.                   
  100.         var pstmt = conn.prepareStatement(sql);
  101.         pstmt.setString(1, userId);
  102.         pstmt.executeUpdate();
  103.         pstmt.close();
  104.         
  105.         logUserActivity(userId, "心跳包", "发送心跳包,更新用户活跃时间");
  106.         print.log("✅ 用户 " + userId + " 心跳包发送成功");
  107.         return true;
  108.     } catch (e) {
  109.         print.log("❌ 心跳包发送失败: " + e.message);
  110.         return false;
  111.     }
  112. }

  113. /**
  114. * 记录用户活动日志
  115. */
  116. function logUserActivity(userId, activityType, details) {
  117.     try {
  118.         var sql = "INSERT INTO 用户活动日志表 (用户ID, 活动类型, 活动详情) VALUES (?, ?, ?)";
  119.         var pstmt = conn.prepareStatement(sql);
  120.         pstmt.setString(1, userId);
  121.         pstmt.setString(2, activityType);
  122.         pstmt.setString(3, details);
  123.         pstmt.executeUpdate();
  124.         pstmt.close();
  125.         return true;
  126.     } catch (e) {
  127.         // 日志记录失败不影响主流程
  128.         print.log("⚠️ 用户活动日志记录失败: " + e.message);
  129.         return false;
  130.     }
  131. }

  132. /**
  133. * 检查用户在线状态
  134. */
  135. function checkUserStatus() {
  136.     try {
  137.         var sql = "SELECT 用户ID, 用户名, 在线状态, 最后活跃时间, 会话开始时间 FROM 用户在线状态表";
  138.         var stmt = conn.createStatement();
  139.         var rs = stmt.executeQuery(sql);
  140.         
  141.         print.log("\n=== 用户在线状态监控 ===");
  142.         print.log("用户ID\t\t用户名\t\t在线状态\t最后活跃时间\t\t\t会话开始时间");
  143.         print.log("-----------------------------------------------------------------------------------------------");
  144.         
  145.         var offlineUsers = [];
  146.         var onlineUsers = [];
  147.         
  148.         while (rs.next()) {
  149.             var userId = rs.getString("用户ID");
  150.             var username = rs.getString("用户名");
  151.             var onlineStatus = rs.getInt("在线状态");
  152.             var lastActive = rs.getTimestamp("最后活跃时间");
  153.             var sessionStart = rs.getTimestamp("会话开始时间");
  154.             
  155.             // 格式化输出
  156.             var nameStr = username + "\t\t";
  157.             if (username.length >= 4) nameStr = username + "\t";
  158.             
  159.             var statusStr = onlineStatus === 1 ? "在线" : "离线";
  160.             
  161.             print.log(userId + "\t" + nameStr + statusStr + "\t\t" + lastActive + "\t" + sessionStart);
  162.             
  163.             // 分类用户
  164.             if (onlineStatus === 1) {
  165.                 onlineUsers.push({id: userId, name: username, lastActive: lastActive});
  166.             } else {
  167.                 offlineUsers.push({id: userId, name: username});
  168.             }
  169.         }
  170.         
  171.         rs.close();
  172.         stmt.close();
  173.         
  174.         // 报告统计信息
  175.         print.log("\n📊 统计信息:");
  176.         print.log("  在线用户数: " + onlineUsers.length);
  177.         print.log("  离线用户数: " + offlineUsers.length);
  178.         
  179.         if (onlineUsers.length > 0) {
  180.             print.log("\n🟢 在线用户列表:");
  181.             for (var i = 0; i < onlineUsers.length; i++) {
  182.                 var user = onlineUsers[i];
  183.                 print.log("  - " + user.name + " (" + user.id + ") 最后活跃: " + user.lastActive);
  184.             }
  185.         }
  186.         
  187.         if (offlineUsers.length > 0) {
  188.             print.log("\n&#128308; 离线用户列表:");
  189.             for (var i = 0; i < offlineUsers.length; i++) {
  190.                 var user = offlineUsers[i];
  191.                 print.log("  - " + user.name + " (" + user.id + ")");
  192.             }
  193.         }
  194.         
  195.         print.log("");
  196.         return true;
  197.     } catch (e) {
  198.         print.log("❌ 用户状态检查失败: " + e.message);
  199.         return false;
  200.     }
  201. }

  202. /**
  203. * 用户登出
  204. */
  205. function userLogout(userId) {
  206.     try {
  207.         // 更新在线时长
  208.         var durationSql = "UPDATE 用户在线状态表 SET 在线时长 = TIMESTAMPDIFF(SECOND, 会话开始时间, NOW()) WHERE 用户ID = ?";
  209.         var pstmt = conn.prepareStatement(durationSql);
  210.         pstmt.setString(1, userId);
  211.         pstmt.executeUpdate();
  212.         pstmt.close();
  213.         
  214.         // 设置为离线状态
  215.         var sql = "UPDATE 用户在线状态表 SET 在线状态 = 0 WHERE 用户ID = ?";
  216.         pstmt = conn.prepareStatement(sql);
  217.         pstmt.setString(1, userId);
  218.         pstmt.executeUpdate();
  219.         pstmt.close();
  220.         
  221.         logUserActivity(userId, "用户登出", "用户登出系统");
  222.         print.log("✅ 用户 " + userId + " 登出成功");
  223.         return true;
  224.     } catch (e) {
  225.         print.log("❌ 用户登出失败: " + e.message);
  226.         return false;
  227.     }
  228. }

  229. /**
  230. * 心跳任务执行函数
  231. */
  232. function executeHeartbeatTask() {
  233.     print.log("\n⏰ 执行用户心跳任务 - " + new Date());
  234.    
  235.     try {
  236.         // 检查数据库连接
  237.         if (!conn || conn.isClosed()) {
  238.             print.log("⚠️ 数据库连接已断开,尝试重新连接...");
  239.             if (!connectDatabase()) {
  240.                 print.log("❌ 无法重新连接数据库,跳过本次心跳任务");
  241.                 return;
  242.             }
  243.         }
  244.         
  245.         // 如果有当前用户,发送心跳包
  246.         if (currentUser) {
  247.             sendUserHeartbeat(currentUser.id);
  248.         }
  249.         
  250.         // 检查所有用户状态
  251.         checkUserStatus();
  252.         
  253.         print.log("✅ 用户心跳任务执行完成\n");
  254.     } catch (e) {
  255.         print.log("❌ 用户心跳任务执行失败: " + e.message);
  256.     }
  257. }

  258. /**
  259. * 启动心跳服务
  260. */
  261. function startHeartbeatService(intervalSeconds) {
  262.     if (isRunning) {
  263.         print.log("⚠️ 心跳服务已经在运行中");
  264.         return false;
  265.     }
  266.    
  267.     // 连接数据库
  268.     if (!connectDatabase()) {
  269.         print.log("❌ 无法启动心跳服务:数据库连接失败");
  270.         return false;
  271.     }
  272.    
  273.     // 初始化数据库
  274.     if (!initializeDatabase()) {
  275.         print.log("❌ 无法启动心跳服务:数据库初始化失败");
  276.         return false;
  277.     }
  278.    
  279.     isRunning = true;
  280.     print.log("✅ 心跳服务启动成功,间隔: " + intervalSeconds + "秒");
  281.    
  282.     // 立即执行一次
  283.     executeHeartbeatTask();
  284.    
  285.     // 设置定时任务
  286.     heartbeatInterval = setInterval(function() {
  287.         executeHeartbeatTask();
  288.     }, intervalSeconds * 1000);
  289.    
  290.     return true;
  291. }

  292. /**
  293. * 停止心跳服务
  294. */
  295. function stopHeartbeatService() {
  296.     if (!isRunning) {
  297.         print.log("⚠️ 心跳服务未在运行");
  298.         return false;
  299.     }
  300.    
  301.     if (heartbeatInterval) {
  302.         clearInterval(heartbeatInterval);
  303.         heartbeatInterval = null;
  304.     }
  305.    
  306.     isRunning = false;
  307.     print.log("✅ 心跳服务已停止");
  308.     return true;
  309. }

  310. /**
  311. * 关闭数据库连接
  312. */
  313. function closeConnection() {
  314.     try {
  315.         if (conn != null) {
  316.             conn.close();
  317.         }
  318.         print.log("✅ 数据库连接已关闭");
  319.     } catch (e) {
  320.         print.log("❌ 关闭连接时出错: " + e.message);
  321.     }
  322. }

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

  336. // 主程序
  337. try {
  338.     print.log("&#128640; 启动用户在线状态管理心跳程序");
  339.    
  340.     // 注册退出处理函数
  341.     java.lang.Runtime.getRuntime().addShutdownHook(new java.lang.Thread({
  342.         run: function() {
  343.             exitHandler();
  344.         }
  345.     }));
  346.    
  347.     // 启动心跳服务 (每30秒执行一次)
  348.     if (startHeartbeatService(30)) {
  349.         print.log("✅ 用户在线状态管理心跳程序已启动");
  350.         print.log("&#128161; 按 Ctrl+C 停止程序");
  351.         
  352.         // 模拟用户登录
  353.         print.log("&#128221; 模拟用户登录...");
  354.         userLogin("USER_001", "张三");
  355.         
  356.         // 保持程序运行
  357.         while (isRunning) {
  358.             java.lang.Thread.sleep(1000);
  359.         }
  360.     } else {
  361.         print.log("❌ 用户在线状态管理心跳程序启动失败");
  362.     }
  363.    
  364. } catch (e) {
  365.     print.log("❌ 程序执行过程中发生错误: " + e.message);
  366.     exitHandler();
  367. }

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







欢迎光临 B2B网络软件 (http://bbs.niubt.cn/) Powered by Discuz! X3.2