using System;
using System.Collections.Generic;
using Ice;
using System.Web.Helpers;
using CommonLang;
using System.Collections.Concurrent;
using Pomelo.JSGModule;
using BattleIce;
namespace Pomelo
{
public class IceLogger : Ice.Logger
{
private log4net.ILog logger;
public IceLogger()
{
this.logger = log4net.LogManager.GetLogger("Ice");
}
public Logger cloneWithPrefix(string prefix)
{
throw new NotImplementedException();
}
public void error(string message)
{
this.logger.Error(message);
}
public string getPrefix()
{
throw new NotImplementedException();
}
public void print(string message)
{
this.logger.Info(message);
}
public void trace(string category, string message)
{
//this.logger.Debug(message);
}
public void warning(string message)
{
this.logger.Warn(message);
}
}
public class IceConfig
{
///
/// 启动host
///
public string host = "127.0.0.1";
///
/// 启动端口
///
public int port;
///
/// 是否输出连接警告
///
public bool isWarnConnections = true;
///
/// 是否输出网络日志
///
public bool isTraceNetwork = false;
///
/// 是否输出协议日志
///
public bool isTraceProtocol = false;
}
/** ice通知消息信息 */
public class ICENotifyData
{
public string name;
public string jsonData; // 通知数据
public long failTime; // 失败时间
public ICENotifyData(string name, string jsonData)
{
this.name = name;
this.jsonData = jsonData;
this.failTime = CommonLang.TimeUtil.GetTimestampMS();
}
}
public class ICEZoneSession
{
private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("ICEZoneSession");
public string srvUUID;
public ZoneManagerCallbackPrx client;
public ZoneManagerCallbackPrx callback;
public IFastSession fastSession;
public int failTimes = 0;
public ConcurrentQueue notifyFailData = new ConcurrentQueue();
public ICEZoneSession(string srvUUID, ZoneManagerCallbackPrx client, ZoneManagerCallbackPrx callback)
{
try
{
this.srvUUID = srvUUID;
this.client = client;
this.callback = callback;
this.failTimes = 0;
}
catch(System.Exception e)
{
log.Error("ICEZoneSession create catch :" + e);
}
}
public bool setFastSession(IFastSession session)
{
this.fastSession = session;
this.failTimes = 0;
return true;
}
/** 重新通知所有时间 */
public void RetryFailNotifys()
{
try
{
this.callback.ice_ping();
}
catch (System.Exception e)
{
log.Warn("RetryFailNotifys ping 异常:", e);
}
try
{
log.Info("RetryFailNotifys start begin 1: " + notifyFailData.Count);
this.callback.ice_ping();
long ltimeEnd = CommonLang.TimeUtil.GetTimestampMS() - 120000;
while (notifyFailData.Count > 0)
{
ICENotifyData notifyData = new ICENotifyData("", "");
if (notifyFailData.TryDequeue(out notifyData) && ltimeEnd < notifyData.failTime)
{
log.Info("RetryFailNotifys start begin 2: " + notifyFailData.Count + ", " + notifyData.name + ", " + notifyData.jsonData + ", time: " + notifyData.failTime);
this.callback.eventNotify(notifyData.name, notifyData.jsonData);
}
else
{
log.Info("RetryFailNotifys start begin 3 skip: " + notifyFailData.Count + ", " + notifyData.name + ", " + notifyData.jsonData + ", time: " + notifyData.failTime);
}
}
}
catch(System.Exception e)
{
log.Error("RetryFailNotifys catch: " + e.Message, e);
}
}
}
public class IceManager : Ice.Application
{
private static IceManager _instance;
private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("IceManager");
private Dictionary proxys;
///
/// 战斗服到游戏服ICE通知
///
private HashMap callbacks = new HashMap();
public ICEZoneSession getCallback(string gameServerId)
{
lock (callbacks)
{
return callbacks.Get(gameServerId);
}
}
public int setCallback(string gameServerId, string srvUUID, ZoneManagerCallbackPrx client, ZoneManagerCallbackPrx callback)
{
lock (callbacks)
{
ICEZoneSession cacheSession = callbacks.Get(gameServerId);
if (cacheSession != null && cacheSession.callback != null)
{
try
{
cacheSession.callback.ice_ping();
log.Error("已有服务器在线ice, 拒绝连接!");
return GSBindResult.ALREADY_EXISTS;
}
catch(System.Exception)
{
try
{
log.Error("ice连入,远端已经失效,重新设置!");
cacheSession.callback = callback;
bool reconnect = cacheSession.srvUUID.Equals(srvUUID);
//重连处理失败的逻辑
if (reconnect)
{
cacheSession.RetryFailNotifys();
}
cacheSession.srvUUID = srvUUID;
return reconnect ? GSBindResult.JOIN_RECONNECT : GSBindResult.JOIN_OK;
}
catch (System.Exception e)
{
log.Error("setCallback未处理异常:", e);
return GSBindResult.UNKOWN;
}
}
}
else
{
callbacks.Put(gameServerId, new ICEZoneSession(srvUUID, client, callback));
}
}
return GSBindResult.JOIN_OK;
}
public bool setFastSession(string gameServerId, IFastSession session)
{
lock (callbacks)
{
ICEZoneSession cacheSession = callbacks.Get(gameServerId);
if (cacheSession != null)
{
if(cacheSession.fastSession != null && cacheSession.fastSession.IsConnected())
{
///sesion.fastSession.doClose();
log.Error("已有服务器在线socket:" + gameServerId + ", " + cacheSession.fastSession.GetDescribe() + ", " + session.GetDescribe());
return false;
}
return cacheSession.setFastSession(session);
}
else
{
log.Error("setFastSession 找不到ice信息:" + gameServerId + ", " + session.ConnectorId + ", " + session.GetDescribe());
return false;
}
}
}
//private ZoneManagerCallbackPrx callback;
//public ZoneManagerCallbackPrx Callback
//{
// get { return callback; }
// set { callback = value; }
//}
///
/// 单件实例
///
///
public static IceManager instance()
{
if (_instance == null)
{
_instance = new IceManager();
}
return _instance;
}
public override int run(string[] args)
{
if (args.Length > 0)
{
log.Error(appName() + ": too many arguments");
return 1;
}
Ice.ObjectAdapter adapter = communicator().createObjectAdapter("CSharp");
foreach (var e in proxys)
{
log.Warn($"add ice adapter: {e.Key}");
adapter.add(e.Value, communicator().stringToIdentity(e.Key));
}
adapter.activate();
log.Info("ICE started !");
communicator().waitForShutdown();
return 0;
}
public int Start(IceConfig config, Dictionary proxys)
{
this.proxys = proxys;
Ice.InitializationData initData = new Ice.InitializationData();
//设置日志
initData.logger = new IceLogger();
initData.logger.print(Json.Encode(config));
//设置参数
initData.properties = Ice.Util.createProperties();
initData.properties.setProperty("CSharp.Endpoints", "tcp -p " + config.port);
initData.properties.setProperty("Ice.Default.Host", config.host);
initData.properties.setProperty("Ice.Warn.Connections", config.isWarnConnections ? "1" : "0");
initData.properties.setProperty("Ice.ACM.Close", "0");
//Ice.ACM.Timeout没有,相当于无用设置
initData.properties.setProperty("Ice.ACM.Heartbeat", "3");
initData.properties.setProperty("Ice.ThreadPool.Server.Size", "4");
initData.properties.setProperty("Ice.ThreadPool.Server.SizeMax", "8");
initData.properties.setProperty("Ice.MessageSizeMax", "10240");
initData.properties.setProperty("Ice.RetryIntervals", "0 500 2000 5000");
initData.properties.setProperty("Ice.Trace.Network", config.isTraceNetwork ? "1" : "0");
initData.properties.setProperty("Ice.Trace.Protocol", config.isTraceProtocol ? "1" : "0");
initData.properties.setProperty("Ice.Trace.Retry", "2");
var thread = new System.Threading.Thread(() =>
{
log.Warn("ICE starting at " + config.host + ":" + config.port);
this.main(new string[0], initData);
});
thread.Name = "ICE run";
thread.Start();
return 0;
}
public void Stop()
{
communicator().shutdown();
communicator().destroy();
}
//public void eventNotify(string eventType, string msg)
//{
// if (callback != null)
// {
// callback.eventNotify(eventType, msg);
// }
//}
//private IceManager(IceConfig config, Dictionary proxys)
//{
// this.config = config;
// this.proxys = proxys;
//}
private IceManager()
{
}
}
}