using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Configuration;
using Core.Mes.Common;
using Core.Mes.IBaseInterface;
namespace Core.Mes.ServerFrameWork
{
public class Dispatcher : MarshalByRefObject, ICommon
{
private ArrayList _objects = null;
private ServerConfigure _servConf = null;
public ServerConfigure ServConfig
{
get { return _servConf; }
}
#region " Construct "
public Dispatcher() { }
public Dispatcher(IServerPool pool, ServerConfigure _conf, ArrayList _objs)
{
Pool = pool;
_servConf = _conf;
_objects = _objs;
}
private IServerPool _pool = null;
public IServerPool Pool
{
get { return _pool; }
set
{
_pool = value;
if (_pool.OwnObjects == null && _objects != null) _pool.OwnObjects = _objects;
}
}
#endregion
#region " Variable "
//== 子服务集合
public static Hashtable _htServers = new Hashtable();
//== 数据链接集合
public static Hashtable htDBManager = new Hashtable();
public event GetStatusInfoHandler getStatusInfo;
public delegate void GetStatusInfoHandler(string info);
protected virtual void SetStatusMessage(string info)
{
if (getStatusInfo != null)
{
getStatusInfo(info);
}
}
#endregion
#region 内存释放
public void MemoryDispose()
{
long memorysize = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
int PagedMemorySize = (int)memorysize / (1024 * 1024);
if (PagedMemorySize > _servConf.MemoryMaxSize)//进程占用内存>100M 做GC.
{
try
{
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
}
catch
{
}
System.Diagnostics.Process.GetCurrentProcess().Dispose();
}
}
#endregion
#region MethodTimeLog
private static object lockObj = new object();
public void MethodTimeLog(TimeSpan tspan, object[] objs, object[] args)
{
string path = string.Format(@"./log/Method/MethodTimeLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
lock (lockObj)
{
using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
{
StringBuilder sbtxt = new StringBuilder();
sbtxt.AppendLine("==============================================");
sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
sbtxt.AppendLine(string.Format("Time:{0}", tspan.TotalMilliseconds));
sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
if (args != null)
{
foreach (object obj in args)
{
if (obj != null)
{
sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
}
}
}
sbtxt.AppendLine("==============================================");
sw.WriteLine(sbtxt.ToString());
}
}
}
public void MethodErrLog(Exception ex, object[] objs, object[] args)
{
string path = string.Format(@"./log/Method/MethodErrLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
lock (lockObj)
{
using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
{
StringBuilder sbtxt = new StringBuilder();
sbtxt.AppendLine("==============================================");
sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
if (args != null)
{
foreach (object obj in args)
{
if (obj != null)
{
sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
}
}
}
sbtxt.AppendLine(ex.Message);
sbtxt.AppendLine(ex.StackTrace);
sbtxt.AppendLine("==============================================");
sw.WriteLine(sbtxt.ToString());
}
}
}
public void DebugLog(object[] objs, object[] args)
{
string path = string.Format(@"./log/Method/DebugLog_{0}.txt", System.DateTime.Now.ToString("yyyy_MM_dd"));
lock (lockObj)
{
if (File.Exists(Path.GetFullPath(path)))
{
FileInfo fileInfo = new FileInfo(Path.GetFullPath(path));
if (fileInfo.Length / (1024 * 1024) > 6)
{
File.Delete(path);
}
}
using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
{
StringBuilder sbtxt = new StringBuilder();
sbtxt.AppendLine("==============================================");
sbtxt.AppendLine(string.Format("LogWriteTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
sbtxt.AppendLine(string.Format("ClassName:{0}", objs[0].ToString()));
sbtxt.AppendLine(string.Format("MethodName:{0}", objs[1].ToString()));
if (args != null)
{
foreach (object obj in args)
{
if (obj != null)
{
sbtxt.AppendLine(string.Format("Parameters:{0}", obj.ToString()));
}
}
}
sbtxt.AppendLine("==============================================");
sw.WriteLine(sbtxt.ToString());
}
}
}
#endregion
#region " 调用服务 "
///
/// 服务端公开给客户端的调用后台服务的方法
///
///
///
public ReturnObject MethodHandler(CallingMessage message, ValidateInfo validateInfo)
{
CallingMessageEx messageEx = new CallingMessageEx();
messageEx.FromCallingMessage(message);
messageEx.RedirectLimit = 0;
messageEx.InnerServerRedirect = true;
ReturnObjectEx rtnObjEx = Execute(messageEx, validateInfo);
ReturnObject rtnObj = new ReturnObject();
rtnObj.ErrCode = rtnObjEx.ErrCode;
rtnObj.ErrMessage = rtnObjEx.ErrMessage;
rtnObj.RealDataSet = rtnObjEx.RealDataSet;
rtnObj.RealObject = rtnObjEx.RealObject;
return rtnObj;
}
public ReturnObjectEx MethodHandlerEx(CallingMessageEx message, ValidateInfo validateInfo)
{
return Execute(message, validateInfo);
}
private ReturnObjectEx Execute(CallingMessageEx messageEx, ValidateInfo validateInfo)
{
//step1:
MemoryDispose();
//step2:
string serverName = messageEx.ServerName;
string assemblyName = messageEx.AssemblyName;
string className = messageEx.ClassName;
string methodName = messageEx.MethodName;
object[] args = messageEx.args;
ReturnObjectEx rtnObjEx = new ReturnObjectEx();
MethodInfo myMethod = null;
try
{
if (Pool.HtComponent.Contains(className))
{
try
{
if (serverName.ToUpper() != "SERVERCOMMON" && messageEx.RedirectLimit > 0)
{
string RedirURL = "";
double sum_factor = 0;
ArrayList serviceProvider = new ArrayList();
ArrayList pfactors = new ArrayList();
serviceProvider.Add("THIS");
sum_factor += this.ServConfig.PriorityFactor;
pfactors.Add(sum_factor);
foreach (string server in Pool.HtExtServer.Keys)
{
RemotingServer rs = (RemotingServer)Pool.HtExtServer[server];
if (rs.Valid != RemoteServerStatus.Normal || rs.Enable == false) continue;
rs.FindRemoteServer(serverName);
if (!rs.HTServices.ContainsKey(serverName)) continue;
ServiceObject so = ((ServiceObject)(rs.HTServices[serverName]));
if (so.Valid != ServiceObjectStatus.Normal || so.Enable == false) continue;
RedirURL = so.URL;
sum_factor += rs.PriorityFactor;
serviceProvider.Add(server);
pfactors.Add(sum_factor);
}
Random rand = new Random();
double rand_selector = rand.NextDouble() * sum_factor;
int selector = 0;
for (int idx = 0; idx < pfactors.Count; idx++)
{
if (rand_selector <= (double)pfactors[idx])
{
selector = idx;
break;
}
}
if (selector != 0)
{
SimpleReturnObject _out = new SimpleReturnObject();
if (messageEx.InnerServerRedirect)
{
RemotingServer rs = (RemotingServer)Pool.HtExtServer[serviceProvider[selector]];
rtnObjEx = (ReturnObjectEx)rs.ExecuteMethod(messageEx, out _out);
return rtnObjEx;
}
else
{
rtnObjEx.ReDirectURL = RedirURL;
return rtnObjEx;
}
}
}
//使用本地服务
myMethod = Pool.GetType().GetMethod("HandleMethodEx"); ;
DateTime startTime = DateTime.Now;
if (_servConf.Debug == "true")
{
DebugLog(new object[] { className, methodName }, args);
}
ReturnObject rtnObj = (ReturnObject)myMethod.Invoke(Pool, new object[] { className, methodName, args, _objects });
rtnObjEx.ReDirectURL = "";
rtnObjEx.ErrCode = rtnObj.ErrCode;
rtnObjEx.ErrMessage = rtnObj.ErrMessage;
rtnObjEx.RealDataSet = rtnObj.RealDataSet;
rtnObjEx.RealObject = rtnObj.RealObject;
DateTime endTime = DateTime.Now;
TimeSpan tspan = endTime - startTime;
if (tspan.TotalMilliseconds > (_servConf.MethodTime * 1000))
{
MethodTimeLog(tspan, new object[] { className, methodName }, args);
}
if (rtnObjEx.RealObject != null)
{
if (rtnObjEx.RealObject.GetType() == typeof(DataSet))
{
DataSet _ds = (DataSet)rtnObjEx.RealObject;
bool largeData = false;
int row_cnt = 0;
foreach (DataTable _dt in _ds.Tables)
{
row_cnt += _dt.Rows.Count;
if (_dt.Rows.Count > _servConf.CompressThreshold || row_cnt > _servConf.CompressThreshold)
{
largeData = true;
break;
}
}
if (largeData)
{
byte[] _rtn = Utility.SerializeDataSet(_ds);
byte[] _rtn_comp = Utility.CompressBytes(_rtn);
DataTable dt_rus = new DataTable("RETURN_RESULT");
dt_rus.Columns.AddRange(new DataColumn[]{
new DataColumn("IsCompressed", System.Type.GetType("System.Int32") ),
new DataColumn("UnCompress_size", System.Type.GetType("System.Int32")),
new DataColumn("Compress_size", System.Type.GetType("System.Int32"))}
);
dt_rus.AcceptChanges();
dt_rus.Rows.Add(new object[] { 1, _rtn.Length, _rtn_comp.Length });
dt_rus.AcceptChanges();
if (rtnObjEx.RealDataSet == null)
{
rtnObjEx.RealDataSet = new DataSet();
}
rtnObjEx.RealDataSet.Tables.Add(dt_rus);
rtnObjEx.RealObject = _rtn_comp;
}
}
}
return rtnObjEx;
}
catch (Exception ex)
{
MethodErrLog(ex, new object[] { className, methodName }, args);
return new ReturnObjectEx(null, ex.Message);
}
finally
{
try
{
if (rtnObjEx.RealObject != null)
{
rtnObjEx.RealObject = null;
}
if (rtnObjEx.RealDataSet != null)
{
rtnObjEx.RealDataSet = null;
}
}
catch { }
}
}
else
{
return new ReturnObjectEx(null, "未找到请求的服务![2]");
}
}
catch (Exception ex)
{
return new ReturnObjectEx(null, "服务调用发生异常! \n" + ex.Message);
}
}
#endregion
#region " Common Handler "
//=======================================================
// 用来确保当创建 Singleton 时, 第一个实例永远不会过期
//=======================================================
public override object InitializeLifetimeService()
{
return null;
}
#endregion
}
}