get_server_info.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //获取玩家区服数据
  2. let mysqlcn = require('../../terry/mysqlcn.js');
  3. let query = mysqlcn.query;
  4. let http = require('http');
  5. let express = require('express');
  6. let router = express.Router();
  7. const timeout = 5000; // 设置超时时间为 5000 毫秒(5 秒)
  8. // 创建一个封装 http 请求的 Promise
  9. function fetchDataFromServer(options, data) {
  10. return new Promise((resolve, reject) => {
  11. const req = http.request(options, (res) => {
  12. let data = '';
  13. res.on('data', (chunk) => {
  14. data += chunk;
  15. });
  16. res.on('end', () => {
  17. resolve(data);
  18. });
  19. });
  20. req.on('error', (e) => {
  21. reject(e);
  22. });
  23. req.write(data)
  24. req.end();
  25. });
  26. }
  27. // 创建一个超时的 Promise
  28. function timeoutPromise(ms) {
  29. return new Promise((_, reject) => {
  30. setTimeout(() => {
  31. reject(new Error('请求超时'));
  32. }, ms);
  33. });
  34. }
  35. // 从多个 URL 获取数据,处理超时
  36. async function fetchAllDataWithTimeout(args, vals, timeout) {
  37. const dataTable = new Array();
  38. const timeoutPromiseInstance = timeoutPromise(timeout);
  39. try {
  40. // 使用 Promise.race 处理超时
  41. for (let i = 0; i < vals.length; i++) {
  42. const url = vals[i];
  43. let data2game = JSON.stringify({
  44. "sid" : vals[i].id,
  45. "channel" : args.channel,
  46. "account" : args.account,
  47. })
  48. let opt = {
  49. method: "POST",
  50. host: vals[i].ip,
  51. port: vals[i].port,
  52. path: "/check_server",
  53. headers: {
  54. "Content-Type": 'application/json',
  55. "Content-Length": Buffer.byteLength(data2game, "utf8")
  56. }
  57. };
  58. dataTable[i] = {
  59. "server_id": vals[i].id,
  60. "server_name": vals[i].name,
  61. "state": 0,
  62. "ip": vals[i].ip,
  63. "port": vals[i].game,
  64. "create": false,
  65. }
  66. const fetchPromise = fetchDataFromServer(opt, data2game);
  67. try {
  68. // 使用 Promise.race 处理每个请求的超时
  69. const result = await Promise.race([fetchPromise, timeoutPromiseInstance]);
  70. console.log(result)
  71. if(result != "Not Found") {
  72. const obj = JSON.parse(result);
  73. if (obj.state == 0){
  74. dataTable[i].state = obj.open? 1:0
  75. dataTable[i].create = obj.create
  76. }
  77. }
  78. } catch(error) {
  79. console.log(error);
  80. }
  81. }
  82. return dataTable;
  83. } catch (error) {
  84. console.error('Error:', error);
  85. throw error; // 重新抛出错误以便调用者处理
  86. }
  87. }
  88. let server_query_info = function(args,res){
  89. let sql = "SELECT * FROM services";
  90. query(sql,function(qerr,vals,fields_){
  91. if (qerr==null){
  92. fetchAllDataWithTimeout(args, vals, timeout)
  93. .then((dataTable) => {
  94. let returndata = JSON.stringify({
  95. 'code': 0,
  96. 'msg': "",
  97. 'data': dataTable,
  98. });
  99. res.send(returndata);
  100. }).catch((error) => {
  101. console.error('Error:', error);
  102. res.send(JSON.stringify({ 'code':'400','msg':'稍后请求'}));
  103. });
  104. }
  105. else{
  106. console.log("打开mysql库中服务器列表失败");
  107. try{
  108. res.send(JSON.stringify({ 'code':'400','msg':'稍后请求'}));
  109. }
  110. catch(e){
  111. console.error('Error:', error);
  112. }
  113. }
  114. });
  115. }
  116. router.post('/server_query_info', (req, res) => {
  117. // 解析请求体中的数据
  118. server_query_info(req.body, res)
  119. });
  120. module.exports = router;