MiddleConnect.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. -- 跨服鏈接和重连管理
  2. local msg_parse = _G.msg_inner_parse
  3. local Config = require("Config")
  4. local Log = require("common.Log")
  5. local CommonDB = require("common.CommonDB")
  6. local InnerMsg = require("core.InnerMsg")
  7. local MiddleManager = require("middle.MiddleManager")
  8. local MiddleHeartBeat = require("middle.MiddleHeartBeat")
  9. local Define = require("platform.Define")
  10. local Json = require("common.Json")
  11. local JjcLadderMiddle = require("jjcLadder.JjcLadderMiddle")
  12. local WarZoneConf = require("excel.WarZone") --- 战区配置
  13. local ChatHandler = require("chat.Handler")
  14. IS_MIDDLE_CONNECT = IS_MIDDLE_CONNECT or nil -- 是否連上跨服 收到WLhello才認為連上了
  15. local nServerOffSet = 810538 -- 配置中服务器ID偏移量
  16. YY_ACT_FLAG = nil
  17. -- 请求middleInfo
  18. local s2aParam = {}
  19. local function questMiddleInfo()
  20. s2aParam.sid = Config.SVR_INDEX
  21. s2aParam.api_cbMethod = "setMiddleInfo"
  22. _G.thread_http.send(Define.MIDDLE_INFO_URL, Json.Encode(s2aParam))
  23. end
  24. -- 获取战区最小和最大服务器ID
  25. local function MiddleConnect_GetWarZoneServer(nSeverID)
  26. local tWarZoneConf = WarZoneConf.group
  27. if not tWarZoneConf then
  28. return 0, 0
  29. end
  30. for _, v in pairs(tWarZoneConf) do
  31. if v.nMinServerID <= nSeverID and v.nMaxServerID >= nSeverID then
  32. return v.nMinServerID, v.nMaxServerID
  33. end
  34. end
  35. return 0, 0
  36. end
  37. function setMiddleInfo(ip, port, host)
  38. if _G.is_middle == true then return end
  39. local middleDBInfo = CommonDB.getMiddleInfo()
  40. if middleDBInfo.ip == ip and middleDBInfo.port == port and middleDBInfo.host == host then
  41. -- 沒變化
  42. return
  43. end
  44. local oldIp = middleDBInfo.ip
  45. local oldPort = middleDBInfo.port
  46. CommonDB.setMiddleInfo(ip, port, host)
  47. if oldIp == ip and oldPort == port then
  48. -- 只有host变了 不需要重連
  49. return
  50. else
  51. tryConnectMiddle(ip, port) -- try的時候會把之前的鏈接斷開
  52. end
  53. end
  54. function getMiddleInfo()
  55. --调试模式使用配置的IP
  56. if Config.IS_DEBUG then
  57. return Config.MIDDLE_IP, Config.MIDDLE_PORT, Config.MIDDLE_HOST
  58. end
  59. local middleDBInfo = CommonDB.getMiddleInfo()
  60. return middleDBInfo.ip, middleDBInfo.port, middleDBInfo.host
  61. end
  62. function initAfterStart()
  63. onTimer() -- 啟動拉取一下middleInfo
  64. end
  65. function onTimer()
  66. if _G.is_middle == true then return end
  67. -- 如果没有middleip 去找后台请求middleip 1分钟1次
  68. local ip, port = getMiddleInfo()
  69. if ip == nil then
  70. -- reyes todo get ip
  71. print("no middleInfo try to get")
  72. questMiddleInfo()
  73. return
  74. end
  75. -- 如果ip有了 但是一直没连上 1分钟重连1次
  76. if isConnect() ~= true then
  77. tryConnectMiddle(ip, port)
  78. return
  79. end
  80. -- 如果3分钟之内 没有收到middle的心跳包 并且底层还是连接中的状态 我们认为出故障了 这个时候重连一下middle 这是一个异常处理
  81. if MiddleHeartBeat.LAST_HEARTBEAT_TIME then
  82. local now = os.time()
  83. if now - MiddleHeartBeat.LAST_HEARTBEAT_TIME > 180 then
  84. stopConnectMiddle()
  85. end
  86. end
  87. end
  88. function autoResetMiddle()
  89. if _G.is_middle == true then return end
  90. -- 每周一凌晨2點 斷開鏈接 并且重新取一下php的跨服信息 重新連新跨服
  91. CommonDB.setMiddleInfo(nil, nil, nil)
  92. stopConnectMiddle()
  93. onTimer() -- 拉取一下middleInfo
  94. end
  95. function isConnect()
  96. -- 這個接口和IS_MIDDLE_CONNECT的區別是 這個表示底層鏈接連上了 但是不一定正確收到了middle會包 lua層業務判斷最好別用這個接口 盡量用IS_MIDDLE_CONNECT
  97. local ret = msg_parse.check_connect()
  98. if ret == true then
  99. return true
  100. end
  101. end
  102. function tryConnectMiddle(ip, port)
  103. print("try connect middle ", ip, port)
  104. Log.write(Log.LOGID_INNER_CLOSE, "tryConnectMiddle", ip, port)
  105. msg_parse.set_connect(ip, port)
  106. end
  107. function stopConnectMiddle()
  108. print("stop connect middle ")
  109. Log.write(Log.LOGID_INNER_CLOSE, "stopConnectMiddle")
  110. msg_parse.close_connect()
  111. IS_MIDDLE_CONNECT = nil
  112. MiddleHeartBeat.LAST_HEARTBEAT_TIME = nil
  113. MiddleHeartBeat.LAST_SEND_HB_TS = nil
  114. end
  115. function LW_HELLO(fd, msg)
  116. --print("LW Hello fd = "..fd)
  117. --table.print_lua_table(msg)
  118. --local stackTrace = debug.traceback("", 2)
  119. --print("[LW_HELLO] 堆栈信息 "..stackTrace)
  120. Log.write(Log.LOGID_INNER_CLOSE, "LW_HELLO")
  121. MiddleManager.addLogicServer(fd, msg.svrIndex)
  122. local szMsgData = InnerMsg.wl.WL_HELLO
  123. --table.print_lua_table(szMsgData)
  124. szMsgData.nGetSvrID = msg.svrIndex
  125. szMsgData.nNowSvrID = Config.SVR_INDEX
  126. --table.print_lua_table(msg)
  127. --table.print_lua_table(szMsgData)
  128. InnerMsg.sendMsg(fd, szMsgData)
  129. msg = InnerMsg.wl.WL_HEARTBEAT
  130. InnerMsg.sendMsg(fd, msg)
  131. -- 同步其它信息
  132. -- JjcLadderMiddle.sendWLMobaiCnt(fd)
  133. end
  134. function WL_HELLO(fd, msg)
  135. print("WL hello")
  136. Log.write(Log.LOGID_INNER_CLOSE, "WL_HELLO")
  137. if not IS_MIDDLE_CONNECT then
  138. print("middle server upup!!!---")
  139. IS_MIDDLE_CONNECT = true
  140. local openTime = CommonDB.getServerOpenTime()
  141. if openTime ~= 0 then
  142. -- local msg = InnerMsg.lw.LW_SET
  143. -- msg.openTime = openTime or 0
  144. -- msg.svrIndex = Config.SVR_INDEX
  145. -- InnerMsg.sendMsg(fd, msg)
  146. end
  147. end
  148. end
  149. function LW_SET(fd,msg)
  150. MiddleManager.setServerOpenDay(fd,msg.svrIndex,msg.openTime)
  151. end
  152. function LW_DISCONNECT(fd, msg)
  153. print("LW_DISCONNECT")
  154. MiddleManager.delLogicServer(fd)
  155. end
  156. --middle断线,C++层触发
  157. function WL_DISCONNECT(fd, msg)
  158. if IS_MIDDLE_CONNECT then
  159. IS_MIDDLE_CONNECT = nil
  160. MiddleHeartBeat.LAST_HEARTBEAT_TIME = nil
  161. MiddleHeartBeat.LAST_SEND_HB_TS = nil
  162. Log.write(Log.LOGID_INNER_CLOSE, "middle server disconnect!!!")
  163. print("middle server disconnect!!!---")
  164. end
  165. end
  166. -- 跨服聊天请求
  167. function LW_MIDDLE_CHAT(fd, msg)
  168. local tAllConnectFD = MiddleManager.MiddleManager_GetAllFD()
  169. if not _G.next(tAllConnectFD) then
  170. print("[LW_MIDDLE_CHAT] 不存在连接上的服务器")
  171. return
  172. end
  173. local szMsgData = InnerMsg.wl.WL_MIDDLE_CHAT
  174. szMsgData.tChatMsg = msg.tChatMsg
  175. local nMsgType = szMsgData.tChatMsg.item.msgType
  176. if ChatHandler.CHAT_TYPE_MIDDLE == nMsgType then
  177. for _, nFD in pairs(tAllConnectFD) do
  178. InnerMsg.sendMsg(nFD, szMsgData)
  179. end
  180. print("[LW_MIDDLE_CHAT] 全服发送消息结束")
  181. elseif ChatHandler.CHAT_TYPE_WARZONE == nMsgType then
  182. local nSendServerID = msg.svrIndex
  183. local nConfServerID = nSendServerID - nServerOffSet + 1
  184. local nMinServerID, nMaxServerID = MiddleConnect_GetWarZoneServer(nConfServerID)
  185. if 0 >= nMinServerID or 0 >= nMaxServerID then
  186. print("[LW_MIDDLE_CHAT 获取不到配置 nSendServerID = "..nSendServerID.." nConfServerID = "..nConfServerID)
  187. return
  188. end
  189. local nServeL, nServerR = nMinServerID + nServerOffSet - 1, nMaxServerID + nServerOffSet - 1
  190. for i = nServeL, nServerR, 1 do
  191. local nFD = MiddleManager.getFDBySvrIndex(i)
  192. if nFD then
  193. InnerMsg.sendMsg(nFD, szMsgData)
  194. else
  195. print("[LW_MIDDLE_CHAT] 不存在对应的fd i = "..i)
  196. end
  197. end
  198. print("[LW_MIDDLE_CHAT] 战区发送消息结束")
  199. else
  200. print("[LW_MIDDLE_CHAT] 未处理的发送消息结束")
  201. end
  202. end
  203. -- 获取聊天英雄信息
  204. function LW_MIDDLE_CHAT_QUERY_HERO_DATA(fd, msg)
  205. local nDesServerID = msg.nDesServerID
  206. local nDesFD = MiddleManager.getFDBySvrIndex(nDesServerID)
  207. if not nDesFD then
  208. print("[LW_MIDDLE_CHAT_QUERY_HERO_DATA] 不存在对应的fd nDesServerID = "..nDesServerID)
  209. return
  210. end
  211. print("[LW_MIDDLE_CHAT_QUERY_HERO_DATA] nDesServerID = "..nDesServerID.." nDesFD = "..nDesFD)
  212. local szMsgData = InnerMsg.wl.WL_MIDDLE_CHAT_QUERY_HERO_DATA
  213. szMsgData.nSrcServerID = msg.nSrcServerID
  214. szMsgData.nSrcUID = msg.nSrcUID
  215. szMsgData.nDesUID = msg.nDesUID
  216. szMsgData.nHeroIndex = msg.nHeroIndex
  217. szMsgData.nChatType = msg.nChatType
  218. InnerMsg.sendMsg(nDesFD, szMsgData)
  219. end
  220. function LW_MIDDLE_CHAT_GET_HERO_DATA(fd, msg)
  221. local nSrcServerID = msg.nSrcServerID
  222. local nSrcFD = MiddleManager.getFDBySvrIndex(nSrcServerID)
  223. if not nSrcFD then
  224. print("[LW_MIDDLE_CHAT_GET_HERO_DATA] 不存在对应的fd nSrcServerID = "..nSrcServerID)
  225. return
  226. end
  227. print("[LW_MIDDLE_CHAT_GET_HERO_DATA] nSrcServerID = "..nSrcServerID.." nSrcFD = "..nSrcFD)
  228. local szMsgData = InnerMsg.wl.WL_MIDDLE_CHAT_GET_HERO_DATA
  229. szMsgData.nSrcUID = msg.nSrcUID
  230. szMsgData.tHeroData = msg.tHeroData
  231. InnerMsg.sendMsg(nSrcFD, szMsgData)
  232. end
  233. function LW_WARREPORT_GET_COMBATINFO(fd, msg)
  234. local nDesServerID = msg.nDesServerID
  235. local nDesFD = MiddleManager.getFDBySvrIndex(nDesServerID)
  236. --local nSrcFD = MiddleManager.getFDBySvrIndex(msg.nSrcServerID)
  237. if not nDesFD then
  238. print("[LW_WARREPORT_GET_COMBATINFO] 不存在对应的fd nDesServerID = "..nDesServerID.." nSrcServerID = "..msg.nSrcServerID)
  239. return
  240. end
  241. local tMsgData = InnerMsg.wl.WL_WARREPORT_GET_COMBATINFO
  242. tMsgData.nSrcUID = msg.nSrcUID
  243. tMsgData.type = msg.type
  244. tMsgData.id = msg.id
  245. tMsgData.nSrcServerID = msg.nSrcServerID
  246. tMsgData.mode = msg.mode
  247. InnerMsg.sendMsg(nDesFD, tMsgData)
  248. end
  249. function LW_WARREPORT_SEND_COMBATINFO(fd, msg)
  250. local nSrcServerID = msg.nSrcServerID
  251. local nSrcFD = MiddleManager.getFDBySvrIndex(nSrcServerID)
  252. if not nSrcFD then
  253. print("[LW_MIDDLE_CHAT_GET_HERO_DATA] 不存在对应的fd nSrcServerID = "..nSrcServerID)
  254. return
  255. end
  256. local tMsgData = InnerMsg.wl.WL_WARREPORT_SEND_COMBATINFO
  257. tMsgData.nSrcUID = msg.nSrcUID
  258. tMsgData.combatInfo = msg.combatInfo
  259. tMsgData.mode = msg.mode
  260. InnerMsg.sendMsg(nSrcFD, tMsgData)
  261. end