IceManager.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. using System;
  2. using System.Collections.Generic;
  3. using Ice;
  4. using System.Web.Helpers;
  5. using CommonLang;
  6. using System.Collections.Concurrent;
  7. namespace Pomelo
  8. {
  9. public class IceLogger : Ice.Logger
  10. {
  11. private log4net.ILog logger;
  12. public IceLogger()
  13. {
  14. this.logger = log4net.LogManager.GetLogger("Ice");
  15. }
  16. public Logger cloneWithPrefix(string prefix)
  17. {
  18. throw new NotImplementedException();
  19. }
  20. public void error(string message)
  21. {
  22. this.logger.Error(message);
  23. }
  24. public string getPrefix()
  25. {
  26. throw new NotImplementedException();
  27. }
  28. public void print(string message)
  29. {
  30. this.logger.Info(message);
  31. }
  32. public void trace(string category, string message)
  33. {
  34. //this.logger.Debug(message);
  35. }
  36. public void warning(string message)
  37. {
  38. this.logger.Warn(message);
  39. }
  40. }
  41. public class IceConfig
  42. {
  43. /// <summary>
  44. /// 启动host
  45. /// </summary>
  46. public string host = "127.0.0.1";
  47. /// <summary>
  48. /// 启动端口
  49. /// </summary>
  50. public int port;
  51. /// <summary>
  52. /// 是否输出连接警告
  53. /// </summary>
  54. public bool isWarnConnections = true;
  55. /// <summary>
  56. /// 是否输出网络日志
  57. /// </summary>
  58. public bool isTraceNetwork = false;
  59. /// <summary>
  60. /// 是否输出协议日志
  61. /// </summary>
  62. public bool isTraceProtocol = false;
  63. }
  64. /** ice通知消息信息 */
  65. public class ICENotifyData
  66. {
  67. public string name;
  68. public string jsonData; // 通知数据
  69. public long failTime; // 失败时间
  70. public ICENotifyData(string name, string jsonData)
  71. {
  72. this.name = name;
  73. this.jsonData = jsonData;
  74. this.failTime = CommonLang.TimeUtil.GetTimestampMS();
  75. }
  76. }
  77. public class ICEZoneSession
  78. {
  79. private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("ICEZoneSession");
  80. public ZoneManagerCallbackPrx client;
  81. public ZoneManagerCallbackPrx callback;
  82. public IFastSession fastSession;
  83. public int failTimes = 0;
  84. public ConcurrentQueue<ICENotifyData> notifyFailData = new ConcurrentQueue<ICENotifyData>();
  85. public ICEZoneSession(ZoneManagerCallbackPrx client, ZoneManagerCallbackPrx callback)
  86. {
  87. try
  88. {
  89. this.client = client;
  90. this.callback = callback;
  91. this.failTimes = 0;
  92. }
  93. catch(System.Exception e)
  94. {
  95. log.Error("ICEZoneSession create catch :" + e);
  96. }
  97. }
  98. public bool setFastSession(IFastSession session)
  99. {
  100. this.fastSession = session;
  101. this.failTimes = 0;
  102. return true;
  103. }
  104. /** 重新通知所有时间 */
  105. public void RetryFailNotifys()
  106. {
  107. try
  108. {
  109. this.callback.ice_ping();
  110. }
  111. catch (System.Exception e)
  112. {
  113. log.Warn("RetryFailNotifys ping 异常:", e);
  114. }
  115. try
  116. {
  117. log.Info("RetryFailNotifys start begin 1: " + notifyFailData.Count);
  118. this.callback.ice_ping();
  119. long ltimeEnd = CommonLang.TimeUtil.GetTimestampMS() - 120000;
  120. while (notifyFailData.Count > 0)
  121. {
  122. ICENotifyData notifyData = new ICENotifyData("", "");
  123. if (notifyFailData.TryDequeue(out notifyData) && ltimeEnd < notifyData.failTime)
  124. {
  125. log.Info("RetryFailNotifys start begin 2: " + notifyFailData.Count + ", " + notifyData.name + ", " + notifyData.jsonData + ", time: " + notifyData.failTime);
  126. this.callback.eventNotify(notifyData.name, notifyData.jsonData);
  127. }
  128. else
  129. {
  130. log.Info("RetryFailNotifys start begin 3 skip: " + notifyFailData.Count + ", " + notifyData.name + ", " + notifyData.jsonData + ", time: " + notifyData.failTime);
  131. }
  132. }
  133. }
  134. catch(System.Exception e)
  135. {
  136. log.Error("RetryFailNotifys catch: " + e.Message, e);
  137. }
  138. }
  139. }
  140. public class IceManager : Ice.Application
  141. {
  142. private static IceManager _instance;
  143. private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("IceManager");
  144. private Dictionary<string, Ice.ObjectImpl> proxys;
  145. /// <summary>
  146. /// 战斗服到游戏服ICE通知
  147. /// </summary>
  148. private HashMap<string, ICEZoneSession> callbacks = new HashMap<string, ICEZoneSession>();
  149. public ICEZoneSession getCallback(string gameServerId)
  150. {
  151. lock (callbacks)
  152. {
  153. return callbacks.Get(gameServerId);
  154. }
  155. }
  156. public int setCallback(string gameServerId, ZoneManagerCallbackPrx client, ZoneManagerCallbackPrx callback)
  157. {
  158. lock (callbacks)
  159. {
  160. ICEZoneSession cacheSession = callbacks.Get(gameServerId);
  161. if (cacheSession != null && cacheSession.callback != null)
  162. {
  163. try
  164. {
  165. cacheSession.callback.ice_ping();
  166. log.Error("已有服务器在线ice, 拒绝连接!");
  167. return 1;
  168. }
  169. catch(System.Exception)
  170. {
  171. log.Error("ice连入,远端已经失效,重新设置!");
  172. cacheSession.callback = callback;
  173. //处理失败的逻辑
  174. cacheSession.RetryFailNotifys();
  175. return 0;
  176. }
  177. }
  178. else
  179. {
  180. callbacks.Put(gameServerId, new ICEZoneSession(client, callback));
  181. }
  182. }
  183. return 0;
  184. }
  185. public bool setFastSession(string gameServerId, IFastSession session)
  186. {
  187. lock (callbacks)
  188. {
  189. ICEZoneSession cacheSession = callbacks.Get(gameServerId);
  190. if (cacheSession != null)
  191. {
  192. if(cacheSession.fastSession != null && cacheSession.fastSession.IsConnected())
  193. {
  194. ///sesion.fastSession.doClose();
  195. log.Error("已有服务器在线socket:" + gameServerId + ", " + cacheSession.fastSession.GetDescribe() + ", " + session.GetDescribe());
  196. return false;
  197. }
  198. return cacheSession.setFastSession(session);
  199. }
  200. else
  201. {
  202. log.Error("setFastSession 找不到ice信息:" + gameServerId + ", " + session.ConnectorId + ", " + session.GetDescribe());
  203. return false;
  204. }
  205. }
  206. }
  207. //private ZoneManagerCallbackPrx callback;
  208. //public ZoneManagerCallbackPrx Callback
  209. //{
  210. // get { return callback; }
  211. // set { callback = value; }
  212. //}
  213. /// <summary>
  214. /// 单件实例
  215. /// </summary>
  216. /// <returns></returns>
  217. public static IceManager instance()
  218. {
  219. if (_instance == null)
  220. {
  221. _instance = new IceManager();
  222. }
  223. return _instance;
  224. }
  225. public override int run(string[] args)
  226. {
  227. if (args.Length > 0)
  228. {
  229. log.Error(appName() + ": too many arguments");
  230. return 1;
  231. }
  232. Ice.ObjectAdapter adapter = communicator().createObjectAdapter("CSharp");
  233. foreach (var e in proxys)
  234. {
  235. adapter.add(e.Value, communicator().stringToIdentity(e.Key));
  236. }
  237. adapter.activate();
  238. log.Info("ICE started !");
  239. communicator().waitForShutdown();
  240. return 0;
  241. }
  242. public int Start(IceConfig config, Dictionary<string, Ice.ObjectImpl> proxys)
  243. {
  244. this.proxys = proxys;
  245. Ice.InitializationData initData = new Ice.InitializationData();
  246. //设置日志
  247. initData.logger = new IceLogger();
  248. initData.logger.print(Json.Encode(config));
  249. //设置参数
  250. initData.properties = Ice.Util.createProperties();
  251. initData.properties.setProperty("CSharp.Endpoints", "tcp -p " + config.port);
  252. initData.properties.setProperty("Ice.Default.Host", config.host);
  253. initData.properties.setProperty("Ice.Warn.Connections", config.isWarnConnections ? "1" : "0");
  254. initData.properties.setProperty("Ice.ACM.Close", "0");
  255. //Ice.ACM.Timeout没有,相当于无用设置
  256. initData.properties.setProperty("Ice.ACM.Heartbeat", "3");
  257. initData.properties.setProperty("Ice.ThreadPool.Server.Size", "4");
  258. initData.properties.setProperty("Ice.ThreadPool.Server.SizeMax", "8");
  259. initData.properties.setProperty("Ice.MessageSizeMax", "10240");
  260. initData.properties.setProperty("Ice.RetryIntervals", "0 500 2000 5000");
  261. initData.properties.setProperty("Ice.Trace.Network", config.isTraceNetwork ? "1" : "0");
  262. initData.properties.setProperty("Ice.Trace.Protocol", config.isTraceProtocol ? "1" : "0");
  263. initData.properties.setProperty("Ice.Trace.Retry", "2");
  264. var thread = new System.Threading.Thread(() =>
  265. {
  266. log.Warn("ICE starting at " + config.host + ":" + config.port);
  267. this.main(new string[0], initData);
  268. });
  269. thread.Name = "ICE run";
  270. thread.Start();
  271. return 0;
  272. }
  273. public void Stop()
  274. {
  275. communicator().shutdown();
  276. communicator().destroy();
  277. }
  278. //public void eventNotify(string eventType, string msg)
  279. //{
  280. // if (callback != null)
  281. // {
  282. // callback.eventNotify(eventType, msg);
  283. // }
  284. //}
  285. //private IceManager(IceConfig config, Dictionary<string, Ice.ObjectImpl> proxys)
  286. //{
  287. // this.config = config;
  288. // this.proxys = proxys;
  289. //}
  290. private IceManager()
  291. {
  292. }
  293. }
  294. }