get_server_info.js 4.6 KB

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