get_role_info.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //获取玩家区服数据
  2. let mysqlcn = require('./mysqlcn.js');
  3. let query = mysqlcn.query;
  4. let http = require('http');
  5. let qs = require('querystring');
  6. let express = require('express');
  7. const { JsonWebTokenError } = require('jsonwebtoken');
  8. let router = express.Router();
  9. const timeout = 5000; // 设置超时时间为 5000 毫秒(5 秒)
  10. let ser_list = {
  11. // shengtian:{
  12. // time : 0,
  13. // data : {}
  14. // }
  15. }
  16. let channel_list= {
  17. shengtian : "FKYBT"
  18. }
  19. function ret_func(errno, data){
  20. let content = {
  21. status:"success",
  22. info:"success",
  23. data:data
  24. }
  25. if (errno != 0) {
  26. content.status = "failure"
  27. content.info = "failure"
  28. content.data = []
  29. }
  30. return JSON.stringify(content)
  31. }
  32. // 创建一个封装 http 请求的 Promise
  33. function fetchDataFromServer(options, data) {
  34. return new Promise((resolve, reject) => {
  35. const req = http.request(options, (res) => {
  36. let data = '';
  37. res.on('data', (chunk) => {
  38. data += chunk;
  39. });
  40. res.on('end', () => {
  41. resolve(data);
  42. });
  43. });
  44. req.on('error', (e) => {
  45. reject(e);
  46. });
  47. req.write(data)
  48. req.end();
  49. });
  50. }
  51. // 创建一个超时的 Promise
  52. function timeoutPromise(ms) {
  53. return new Promise((_, reject) => {
  54. setTimeout(() => {
  55. reject(new Error('请求超时'));
  56. }, ms);
  57. });
  58. }
  59. // 从多个 URL 获取数据,处理超时
  60. async function fetchAllDataWithTimeoutRole(args, vals, timeout) {
  61. if(vals.length <= 0){
  62. return []
  63. }
  64. const dataTable = new Array();
  65. const timeoutPromiseInstance = timeoutPromise(timeout);
  66. try {
  67. console.log(vals)
  68. // 使用 Promise.race 处理超时
  69. for (let i = 0; i < vals.length; i++) {
  70. const url = vals[i];
  71. let data2game = JSON.stringify({
  72. "sid" : vals[i].id,
  73. "channel" : args.channel,
  74. "account" : args.account,
  75. })
  76. let opt = {
  77. method: "POST",
  78. host: vals[i].ip,
  79. port: vals[i].port,
  80. path: "/check_role",
  81. headers: {
  82. "Content-Type": 'application/json',
  83. "Content-Length": Buffer.byteLength(data2game, "utf8")
  84. }
  85. };
  86. const fetchPromise = fetchDataFromServer(opt, data2game);
  87. try {
  88. // 使用 Promise.race 处理每个请求的超时
  89. const result = await Promise.race([fetchPromise, timeoutPromiseInstance]);
  90. // console.log(result)
  91. if(result != "Not Found") {
  92. const obj = JSON.parse(result);
  93. if(obj.create){
  94. dataTable.push({
  95. "serverId": vals[i].id,
  96. "serverName": vals[i].name,
  97. "actor": obj.name,
  98. "level": obj.level,
  99. "roleId": obj.uid,
  100. "createTime": obj.createtime,
  101. })
  102. }
  103. }
  104. } catch(error) {
  105. // console.log(error);
  106. }
  107. }
  108. return dataTable;
  109. } catch (error) {
  110. console.error('Error:', error);
  111. throw error; // 重新抛出错误以便调用者处理
  112. }
  113. }
  114. let query_role_fun = function(args,data, res){
  115. fetchAllDataWithTimeoutRole(args, data, timeout)
  116. .then((dataTable) => {
  117. res.send(ret_func(0, dataTable));
  118. }).catch((error) => {
  119. console.error('Error:', error);
  120. res.send(ret_func(1));
  121. });
  122. }
  123. let server_role_info = function(args,res){
  124. args = args ? args : {}
  125. if (args.gameCode == null || args.uid == null) {
  126. res.send(ret_func(1))
  127. return
  128. }
  129. let channel = ""
  130. let account = args.uid
  131. let gameCode = args.gameCode
  132. for (const [key, value] of Object.entries(channel_list)) {
  133. console.log(key, value);
  134. if (gameCode == value){
  135. channel = key
  136. break;
  137. }
  138. }
  139. if (channel=="") {
  140. res.send(ret_func(1))
  141. return
  142. }
  143. let info = {
  144. channel : channel,
  145. account : account
  146. }
  147. channel = args.channel ? args.channel : ""
  148. const timestamp = Date.now();
  149. if (ser_list[channel] && ser_list[channel].time > timestamp){
  150. query_role_fun(args, ser_list[channel].data, res)
  151. }
  152. else{
  153. let sql = `SELECT * FROM list where channel = "${channel}"`;
  154. query(sql,function(qerr,vals,fields_){
  155. if (qerr==null){
  156. ser_list[channel] = {
  157. time:timestamp+60000,
  158. data:vals,
  159. }
  160. query_role_fun(info, vals, res)
  161. }
  162. else{
  163. console.log("打开mysql库中服务器列表失败");
  164. try{
  165. res.send(ret_func(1));
  166. }
  167. catch(e){
  168. console.error('Error:', error);
  169. }
  170. }
  171. });
  172. }
  173. }
  174. let role_info = function(args,res){
  175. console.log("role_info 回调接收:%s", args);
  176. try {
  177. let receipt = qs.parse(args)
  178. server_role_info(receipt, res)
  179. } catch(e) {
  180. console.log(e)
  181. res.send(ret_func(1));
  182. return;
  183. }
  184. }
  185. router.get('/role_info', function(req, res) {
  186. let pos = req.url.indexOf('?')
  187. let str = req.url
  188. if (pos == -1) { //请求的url是否包含?包含返回-1,==-1为不包含
  189. console.log("role_info 回调接收未找到参数");
  190. res.send(ret_func(1));
  191. } else {
  192. let data = str.substring(pos+1, str.length)
  193. role_info(data, res)
  194. };
  195. req.on("error",function(err){
  196. console.log("error:%s",err);
  197. res.send(ret_func(1));
  198. });
  199. });
  200. module.exports = router;