using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.ComponentModel;
namespace FObjBase
{
public enum SENSE_CONFIG
{
ADD, REMOVE
}
///
/// 建议使用方法:
/// 做为客户端,都使用 FObjSys.Current 连接不同的客户端
/// 做为服务器,当要提供2个Obj服务, 应该要使用 Currents[index]
/// 这套逻辑已经潜入到 每个 FObj 中, FObj.CurrObjSys, 就是对应的 Obj服务
///
public class FObjSys : IFObjSysAsClient, IFObjSysAsServer
{
public static FObjSys Current;
public static List Currents = new List();
TCPListen m_tcplisten;
Dictionary> m_cconns = new Dictionary>();//管理连接到异地服务器的连接
List m_serverConnectedNotifyObjID = new List();//作为服务器,当客户端断开,发送通知
///
/// 交易列表
///
List Transactions = new List();
///
/// 消息推送的敏感对象
///
class Sense
{
public IFConn conn;
public UInt32 objid;
public UInt32 sense_mask;
//public bool hasPush;
}
Dictionary> Objs = new Dictionary>();
static FObjSys()
{
Currents.Add(new FObjBase.FObjSys());
Current = Currents[0];
}
public FObjSys() {
}
#region IFObjSys
///
/// 添加OBJ到系统
///
///
public void ObjAdd(IFObj obj)
{
if (obj.ID == 0)
obj.ID = GetFreeObjID();
Objs.Add(obj, new List());
}
///
/// 对外发送消息
///
/// 远端对应的连接代理
/// 远端的ID
/// 本地的ID
/// 交易码
/// 信息码
/// 信息内容
public void SendMessageEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt32 magic, UInt16 info_no, byte[] info_data)
{
if (s1 == null)
return;
if (s1 is FConnLocal)
{
return;
}
else
{
((TCPConn)s1).SendPacket(new Pack_Proto()
{
destid = destid,
srcid = srcid,
magic = magic,
info = info_no,
buf = info_data
}.ToBytes());
return;
}
}
#region 服务端
//启动本地OBJSys网络
public void Start_Conn_Server(IPEndPoint ep, params UInt32[] objids)
{
m_serverConnectedNotifyObjID.AddRange(objids);
if (m_tcplisten == null)
{
m_tcplisten = new TCPListen(ep)
{
ParsePacket = new ParsePacketHandler(ParsePacketInServer),
ConnectAction = new ConnectHandler(SConnConnectAction),
};
}
else
{
m_tcplisten.Enable = false;
m_tcplisten.LocalEP = ep;
}
m_tcplisten.Enable = true;
}
///
/// 指定推送到某个远端
///
///
///
///
///
///
public void PushObjInfoEx(IFObj srcobj, UInt16 infoid, byte[] infodata, IFConn s1, UInt32 destid)
{
if (s1 is FConnLocal)
{
IFObj obj = Find(destid);
if (obj != null)
obj.PushInfo(s1, srcobj.ID, infoid, infodata);
return;
}
List buf = new List();
buf.AddRange(BitConverter.GetBytes(infoid));
buf.AddRange(infodata);
SendMessageEx(s1, destid, srcobj.ID, 0x1234, Proto.INFO_PUSH_EVENT, buf.ToArray());
}
///
/// 推送到远端,系统判定根据敏感对象推送
///
///
///
///
public void PushObjInfoEx(IFObj srcobj, UInt16 infoid, byte[] infodata)
{
if (!Objs.Keys.Contains(srcobj))
return;
List senses = Objs[srcobj];
//foreach (Sense sense in senses)
// sense.hasPush = false;
int cnt = senses.Count();
for (int i = 0; i < cnt; i++)
{
Sense sense = senses[i];
//if (sense.hasPush == false)
{
if ((sense.sense_mask & (1 << infoid)) == 0)
continue;
if (sense.conn is FConnLocal)
{
IFObj obj = Find(sense.objid);
if (obj != null)
obj.PushInfo(sense.conn, srcobj.ID, infoid, infodata);
}
else
{
List buf = new List();
buf.AddRange(BitConverter.GetBytes(infoid));
buf.AddRange(infodata);
SendMessageEx(sense.conn, sense.objid, srcobj.ID, 0x1234, Proto.INFO_PUSH_EVENT, buf.ToArray());
}
//sense.hasPush = true;
}
}
}
///
/// 推送到远端,系统判定根据敏感对象推送,但不推送给特定某对象
///
///
///
///
///
///
public void PushObjInfoEx_except(IFObj srcobj, UInt16 infoid, byte[] infodata, IFConn except_s1, UInt32 except_destid)
{
if (!Objs.Keys.Contains(srcobj))
return;
List senses = Objs[srcobj];
//foreach (Sense sense in senses)
// sense.hasPush = false;
int cnt = senses.Count();
for (int i = 0; i < cnt; i++)
{
Sense sense = senses[i];
//if (sense.hasPush == false)
{
if ((sense.sense_mask & (1 << infoid)) == 0)
continue;
if ((sense.conn == except_s1) && (sense.objid == except_destid))
continue;
List buf = new List();
buf.AddRange(BitConverter.GetBytes(infoid));
buf.AddRange(infodata);
SendMessageEx(sense.conn, sense.objid, srcobj.ID, 0x1234, Proto.INFO_PUSH_EVENT, buf.ToArray());
//sense.hasPush = true;
}
}
}
///
/// 回复 客户端的CallFunction
///
/// 客户端对应的连接代理
/// 客户端的对象ID
/// 本地服务端的对象ID
/// 交易码
/// 函数ID
/// 函数返回
public void PushCallFunctionEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt32 magic, UInt16 funcid, byte[] retdata)
{
if (s1 == null)
return;
if (s1 is FConnLocal)
{
var ts = from t in Transactions where t.Magic == magic && t.Conn == s1 select t;
if (ts.Count() > 0)
{
Transaction tran = ts.First();
Transactions.Remove(tran);
PushCallFunction(s1, srcid, destid, magic, funcid, retdata, tran.AsyncDelegate, tran.AsyncState);
}
else
{
PushCallFunction(s1, srcid, destid, magic, funcid, retdata, null, null);
}
return;
}
if ((retdata != null) && (retdata.Length > Transaction.PackSize)) //参数太大,需要分包多次发送
{
var ts = from t in Transactions where t.Magic == magic && t.Conn == s1 select t;
if (ts.Count() == 0)
{
Transaction t = new Transaction()
{
Conn = s1,
SrcObjID = destid,
Magic = magic,
Size = retdata.Length,
Buf = (byte[])retdata.Clone(),
FuncID = funcid
};
Transactions.Add(t);
}
PushCallFunctionEx_ReponseBigSize(s1, destid, srcid, magic);
}
else
{
Pack_GetSetPushCall p = new Pack_GetSetPushCall();
p.infoid = funcid;
p.infodata = retdata;
SendMessageEx(s1, destid, srcid, magic, Proto.INFO_PUSH_CALL_FUNCTION, p.ToBytes());
}
}
void PushCallFunctionEx_ReponseBigSize(
IFConn conn, UInt32 destid, UInt32 srcid, UInt32 magic)
{
var ts = from t in Transactions where t.Magic == magic && t.Conn == conn select t;
if (ts.Count() == 0)
return;
Transaction tran = ts.First();
Pack_BigSize pack;
if (tran.GetBigSize(out pack))
Transactions.Remove(tran);//用完了,删除!!!
SendMessageEx(conn, destid, srcid, magic,
Proto.INFO_PUSH_CALL_FUNCTION_REPONSE_BIGSIZE, pack.ToBytes());
}
#endregion
#region 客户端
///
/// 获取没用使用的OBJID
///
///
public UInt32 GetFreeObjID()
{
if (Objs.Count > 0)
return Objs.Max(obj => obj.Key.ID) + 1;
else
return 1;
}
///
/// 从系统删除OBJ
///
///
public void ObjRemove(IFObj obj)
{
Objs.Remove(obj);//作为服务端,关闭推送服务
foreach (var kv in m_cconns)
{
kv.Value.Remove(obj.ID);
}
}
///
/// 作为客户端,从系统删除OBJ;
/// 还会通知服务器,断开与这个 OBJ 的所有连接
///
///
///
public void ObjRemove(IFObj obj, IFConn conn)
{
ObjRemove(obj);
Transactions.RemoveAll(t => t.SrcObjID == obj.ID);
if (conn != null)
{
SendMessageEx(conn, 0, obj.ID, GetFreeMagic(),
Proto.INFO_OBJ_DISPOSE, null);
}
}
///
/// 连接到远端的OBJSys连接
///
/// 远端地址
/// 连接成功后,通知这些obj
///
public TCPCConn Connect_to_Another_OBJSys(IPEndPoint ep, params UInt32[] objids)
{
try
{
KeyValuePair> cc_kv;
cc_kv = m_cconns.First(_cc => _cc.Key.RemoteEP.Equals(ep));
cc_kv.Value.AddRange(objids);
//已经存在此连接,通知
if (cc_kv.Key.IsConnected)
{
foreach (UInt32 objid in objids)
{
IFObj obj = Find(objid);
if (obj != null)
obj.ConnectNotify(cc_kv.Key);
}
}
return cc_kv.Key;
}
catch
{
TCPCConn conn = new TCPCConn(ep)
{
ParsePacket = new ParsePacketHandler(ParsePacketInClient),
ConnectAction = new ConnectHandler(CConnConnectAction),
Enable = true
};
m_cconns.Add(conn, new List(objids));
return conn;
}
}
///
/// 断开到远端OBJSys的连接
///
/// 远端地址
/// 连接成功后,通知这些obj
///
public void Disconnect_to_Another_OBJSys(IPEndPoint ep, params UInt32[] objids)
{
try
{
KeyValuePair> cc_kv;
cc_kv = m_cconns.First(_cc => _cc.Key.RemoteEP.Equals(ep));
cc_kv.Value.RemoveAll(objid => objids.Contains(objid));
//删除大通讯的trans
Transactions.RemoveAll(t => objids.Contains(t.SrcObjID));
if (cc_kv.Key.IsConnected)//它的连接是正常的,通知objids,说连接断开了
{
foreach (UInt32 objid in objids)
{
IFObj obj = Find(objid);
if (obj != null)
obj.ConnectNotify(
new TCPCConn(ep)
{
Enable = false
});
}
}
if (cc_kv.Value.Count == 0)//已经没有obj需要连接了,删除conn
{
cc_kv.Key.Enable = false;
m_cconns.Remove(cc_kv.Key);
}
}
catch
{
}
}
///
/// 注册本地obj 为远端obj的敏感对象,得到远端obj的推送消息
///
/// 远端对应的连接代理
/// 远端的ID
/// 本地obj
/// 注册的敏感源
/// 动作,添加?删除?
public void SenseConfigEx(IFConn s1, UInt32 objid, UInt32 senobjid, UInt32 sense_mask, SENSE_CONFIG action)
{
if (s1 == null)
return;
List buf = new List();
if (action == SENSE_CONFIG.ADD)
buf.Add(0);
else
buf.Add(1);
buf.AddRange(BitConverter.GetBytes(sense_mask));
SendMessageEx(s1, objid, senobjid, GetFreeMagic(), Proto.INFO_CONFIG_SENSE_OBJ, buf.ToArray());
}
///
/// 向远端GetValue
///
/// 远端对应的连接代理
/// 远端的ID
/// 本地的ID
/// 成员ID
public void GetValueEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt16 memid)
{
if (s1 == null)
return;
if (s1 is FConnLocal)
{
byte[] value;
GetValue(s1, srcid, destid, memid, out value);
if (value != null)
PushGetValue(s1, destid, srcid, memid, value);
return;
}
else
{
UInt32 magic = GetFreeMagic();
SendMessageEx(s1, destid, srcid, magic, Proto.INFO_GET_VALUE, BitConverter.GetBytes(memid));
}
}
///
/// 向远端SetValue
///
/// 远端对应的连接代理
/// 远端的ID
/// 本地的ID
/// 成员ID
/// 成员内容
public void SetValueEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt16 memid, byte[] value)
{
if (s1 == null)
return;
if (s1 is FConnLocal)
{
SetValue(s1, srcid, destid, memid, value);
return;
}
List buf = new List();
buf.AddRange(BitConverter.GetBytes(memid));
buf.AddRange(value);
UInt32 magic = GetFreeMagic();
SendMessageEx(s1, destid, srcid, magic, Proto.INFO_SET_VALUE, buf.ToArray());
return;
}
///
/// 向远端CallFunction
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
/// 函数ID
/// 函数参数
/// 在其上调用异步调用的委托对象
/// 作为 BeginInvoke 方法调用的最后一个参数而提供的对象
public UInt32 CallFunctionEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt16 funcid, byte[] param, object AsyncDelegate, object AsyncState)
{
if (s1 == null)
return 0;
if (s1 is FConnLocal)
{
UInt32 magic = GetFreeMagic();
if ((AsyncDelegate != null) || (AsyncState != null)) //需要返回参数!!!
{
Transaction t = new Transaction()
{
Conn = s1,
SrcObjID = destid,
Magic = magic,
AsyncDelegate = AsyncDelegate,
AsyncState = AsyncState
};
Transactions.Add(t);
}
CallFunction(s1, srcid, destid, magic, funcid, param);
return magic;
}
if ((param != null) && (param.Length > Transaction.PackSize)) //参数太大,需要分包多次发送
{
UInt32 magic = GetFreeMagic();
Transaction t = new Transaction()
{
Conn = s1,
SrcObjID = srcid,
Magic = magic,
AsyncDelegate = AsyncDelegate,
AsyncState = AsyncState,
Size = param.Length,
Buf = (byte[])param.Clone(),
FuncID = funcid
};
Transactions.Add(t);
CallFunctionEx_RequestBigSize(s1, destid, srcid, magic);
return magic;
}
else
{
Pack_GetSetPushCall pack = new Pack_GetSetPushCall();
pack.infoid = funcid;
pack.infodata = param;
UInt32 magic = GetFreeMagic();
if ((AsyncDelegate != null) || (AsyncState != null)) //需要返回参数!!!
{
Transaction t = new Transaction()
{
Conn = s1,
SrcObjID = srcid,
Magic = magic,
AsyncDelegate = AsyncDelegate,
AsyncState = AsyncState
};
Transactions.Add(t);
}
SendMessageEx(s1, destid, srcid, magic, Proto.INFO_CALL_FUNCTION, pack.ToBytes());
return magic;
}
}
///
/// 向远端CallFunction
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
/// 函数ID
/// 函数参数
public UInt32 CallFunctionEx(IFConn s1, UInt32 destid, UInt32 srcid, UInt16 funcid, byte[] param)
{
return CallFunctionEx(s1, destid, srcid, funcid, param, null, null);
}
void CallFunctionEx_RequestBigSize(
IFConn conn, UInt32 destid, UInt32 srcid, UInt32 magic)
{
var ts = from t in Transactions where t.Magic == magic && t.Conn == conn select t;
if (ts.Count() == 0)
return;
Transaction tran = ts.First();
Pack_BigSize pack;
if (tran.GetBigSize(out pack))
{
if (tran.Reset())
{
Transactions.Remove(tran);//完成,可以删除
}
}
SendMessageEx(conn, destid, srcid, magic,
Proto.INFO_CALL_FUNCTION_REQUEST_BIGSIZE, pack.ToBytes());
}
#endregion
#endregion
///
/// 通过objid 查找 obj
///
///
///
IFObj Find(UInt32 objid)
{
try
{
KeyValuePair> obj_kv = Objs.First(obj => obj.Key.ID == objid);
return obj_kv.Key;
}
catch
{
return null;
}
}
UInt32 free_magic = 1;
///
/// 获取一个没有被分配的 交易码
///
///
UInt32 GetFreeMagic()
{
UInt32 f = free_magic;
free_magic++;
if (free_magic == 0)
free_magic++;
//if (free_magic > UInt32.MaxValue)
// freetranno = 1;
return f;
}
///
/// 作为客户端,与服务器连续状态改变
///
///
void CConnConnectAction(IFConn conn)
{
TCPCConn cc = (TCPCConn)conn;
KeyValuePair> cc_kv;
try
{
cc_kv = m_cconns.First(_cc => _cc.Key == cc);
foreach (UInt32 objid in cc_kv.Value)
{
IFObj obj = Find(objid);
if (obj != null)
obj.ConnectNotify(cc);
}
}
catch
{
}
}
///
/// 作为服务器端,客户的登陆与退出
///
///
void SConnConnectAction(IFConn conn)
{
//通知obj 连接状态
foreach (UInt32 objid in m_serverConnectedNotifyObjID)
{
IFObj obj = Find(objid);
if (obj != null)
obj.ConnectNotify(conn);
}
//当通讯断开时,还要把关注的推送删除掉
if(conn.IsConnected==false)
{
for (int i = 0; i < Objs.Keys.Count(); i++)
{
List senses = Objs.ElementAt(i).Value;
senses.RemoveAll(s => s.conn == conn);
}
//删除所有与它有关的 tran
Transactions.RemoveAll(t => t.Conn == conn);
}
}
///
/// 作为服务器端,客户端 的 某obj 注销了,把它相关的都删除
///
///
///
void ClearRemoteObjConn(IFConn conn, UInt32 srcid)
{
//删除推送
for (int i = 0; i < Objs.Keys.Count(); i++)
{
List senses = Objs.ElementAt(i).Value;
senses.RemoveAll(s => (s.conn == conn) && (s.objid == srcid));
}
//删除所有与它有关的 tran
Transactions.RemoveAll(t => t.Conn == conn && t.SrcObjID == srcid);
}
#region 本地,给Protocol的函数指针
///
/// 本地,给Protocol的函数指针;
/// GetValue
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
///
///
///
void GetValue(IFConn from,UInt32 srcid,UInt32 destid, UInt16 memid,out byte[] value)
{
value = null;
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.GetValue(from, srcid,memid,out value);
}
///
/// 本地,给Protocol的函数指针;
/// SetValue
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
///
///
void SetValue(IFConn from, UInt32 srcid, UInt32 destid, UInt16 memid, byte[] value)
{
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.SetValue(from, srcid, memid, value);
}
///
/// 本地,给Protocol的函数指针;
/// CallFunction
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
///
///
///
///
void CallFunction(IFConn from, UInt32 srcid, UInt32 destid, UInt32 magic, UInt16 funcid, byte[] param)
{
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.CallFunction(from, srcid, magic, funcid, param);
}
///
/// 本地,给Protocol的函数指针;
/// Sense_Config
///
/// 远端对应的连接代理
/// 远端对象ID
/// 本地对象ID
/// 远端对象 关注 本地对象 的敏感源
/// 动作,添加?删除?
void Sense_Config(IFConn from, UInt32 srcid, UInt32 destid, UInt32 sense_mask, SENSE_CONFIG action)
{
try
{
KeyValuePair> obj_kv = Objs.First(obj => obj.Key.ID == destid);
Sense sense = obj_kv.Value.Find(s=>s.conn == from && s.objid==srcid);
if (sense == null)
{
if (action == SENSE_CONFIG.ADD)
{
Sense s = new Sense() { conn = from, objid = srcid, sense_mask = sense_mask };
obj_kv.Value.Add(s);
}
}
else
{
if (action == SENSE_CONFIG.ADD)
{
sense.sense_mask |= sense_mask;
}
else
{
sense.sense_mask &= ~sense_mask;
}
}
}
catch
{
//不能找到对应的objid
}
}
void PushObjInfo(IFConn from, UInt32 srcid, UInt32 destid, UInt16 infoid, byte[] infodata)
{
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.PushInfo(from, srcid, infoid, infodata);
}
void PushGetValue(IFConn from, UInt32 srcid, UInt32 destid, UInt16 infoid, byte[] infodata)
{
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.PushGetValue(from, srcid, infoid, infodata);
}
void PushCallFunction(IFConn from, UInt32 srcid, UInt32 destid, UInt32 magic, UInt16 infoid, byte[] infodata, object AsyncDelegate, object AsyncState)
{
IFObj destobj = Find(destid);
if (destobj == null)
return;
destobj.PushCallFunction(from, srcid, magic, infoid, infodata, AsyncDelegate, AsyncState);
}
int Process(IFConn from, UInt32 srcid, UInt32 destid, UInt32 magic, UInt16 info_no, byte[] infodata, out byte[] retdata)
{
retdata = null;
IFObj destobj = Find(destid);
if (destobj == null)
return -1;
return destobj.ProcessEx(from, srcid, magic, info_no, infodata,out retdata);
}
#endregion
DateTime dtlast = DateTime.Now;
///
/// 从异端接收的数据,解释数据
///
///
///
///
bool ParsePacketInClient(byte[] packet, IFConn conn)
{
//DateTime dt2 = DateTime.Now;
Pack_Proto p = new Pack_Proto();
if (!p.TryParse(packet))
return false;
conn.TranID = p.magic;
{
byte[] idata = p.buf;
byte[] retdata;
if (Process(conn, p.srcid, p.destid, p.magic, p.info, idata, out retdata) == 0)
{
if (retdata != null)
{
SendMessageEx(conn,p.srcid,p.destid,p.magic,p.info,retdata);
}
return true;
}
}
switch (p.info)
{
case Proto.INFO_PUSH_EVENT:
{
Pack_GetSetPushCall pack = new Pack_GetSetPushCall();
if (!pack.TryParse(p.buf))
return false;
PushObjInfo(conn, p.srcid, p.destid, pack.infoid, pack.infodata);
}break;
case Proto.INFO_PUSH_GET_VALUE:
{
Pack_GetSetPushCall pack = new Pack_GetSetPushCall();
if (!pack.TryParse(p.buf))
return false;
PushGetValue(conn, p.srcid, p.destid, pack.infoid, pack.infodata);
}break;
case Proto.INFO_PUSH_CALL_FUNCTION:
{
Pack_GetSetPushCall pack = new Pack_GetSetPushCall();
if (!pack.TryParse(p.buf))
return false;
var ts = from t in Transactions where (t.Magic == p.magic) && (t.Conn == conn) select t;
if (ts.Count() > 0)
{
Transaction tran = ts.First();
Transactions.Remove(tran);//用完,删除
PushCallFunction(conn, p.srcid, p.destid, p.magic, pack.infoid, pack.infodata, tran.AsyncDelegate, tran.AsyncState);
}
else
{
PushCallFunction(conn, p.srcid, p.destid, p.magic, pack.infoid, pack.infodata, null, null);
}
} break;
case Proto.INFO_PUSH_CALL_FUNCTION_REQUEST_BIGSIZE:
{
CallFunctionEx_RequestBigSize(conn, p.srcid, p.destid, p.magic);
} break;
case Proto.INFO_PUSH_CALL_FUNCTION_REPONSE_BIGSIZE:
{
Pack_BigSize pack = new Pack_BigSize();
if (!pack.TryParse(p.buf))
return false;
var ts = from t in Transactions where t.Conn == conn && t.Magic == p.magic select t;
Transaction tran;
if (ts.Count() == 0)
{
tran = new Transaction()
{
Conn = conn,
SrcObjID = p.destid,
Magic = p.magic
};
Transactions.Add(tran);
}
else
{
tran = ts.First();
}
if (!tran.ToBuf(pack))
{
//继续获取参数!!!!!!!!!
SendMessageEx(conn, p.srcid, p.destid, p.magic,
Proto.INFO_CALL_FUNCTION_REPONSE_BIGSIZE, null);
}
else
{
Transactions.Remove(tran);//用完了,删除!!!
PushCallFunction(conn, p.srcid, p.destid, p.magic, tran.FuncID, tran.Buf, tran.AsyncDelegate, tran.AsyncState);
}
} break;
}
//DateTime dt1 = DateTime.Now;
//Console.WriteLine("FObjSys ParsePacketInClient " + "p.info=" + p.info.ToString() + " " + (dt1 - dt2).TotalMilliseconds.ToString() + " " + (dt1 - dtlast).TotalMilliseconds.ToString());
//dtlast = dt1;
return true;
}
///
/// 从异端接收的数据,解释数据
///
///
///
///
bool ParsePacketInServer(byte[] packet, IFConn conn)
{
//DateTime dt2 = DateTime.Now;
Pack_Proto p = new Pack_Proto();
if (!p.TryParse(packet))
return false;
conn.TranID = p.magic;
{
byte[] idata = p.buf;
byte[] retdata;
if (Process(conn, p.srcid, p.destid, p.magic, p.info, idata, out retdata) == 0)
{
if (retdata != null)
{
SendMessageEx(conn, p.srcid, p.destid, p.magic, p.info, retdata);
}
return true;
}
}
switch (p.info)
{
case Proto.INFO_SET_VALUE:
{
int index = 0;
UInt16 memid = BitConverter.ToUInt16(p.buf, index);
index += 2;
int len = p.buf.Length - index;
byte[] value = new byte[len];
Array.Copy(p.buf, index, value, 0, value.Length);
SetValue(conn, p.srcid, p.destid, memid, value);
} break;
case Proto.INFO_GET_VALUE:
{
int index = 0;
UInt16 memid = BitConverter.ToUInt16(p.buf, index);
index += 2;
byte[] value;
GetValue(conn, p.srcid, p.destid, memid, out value);
if (value != null)
{
List buf = new List();
buf.AddRange(BitConverter.GetBytes(memid));
buf.AddRange(value);
SendMessageEx(conn, p.srcid, p.destid, p.magic,
Proto.INFO_PUSH_GET_VALUE,
buf.ToArray());
}
} break;
case Proto.INFO_CALL_FUNCTION:
{
int index = 0;
UInt16 memid = BitConverter.ToUInt16(p.buf, index);
index += 2;
int len = p.buf.Length - index;
byte[] value = null;
if (len > 0)
{
value = new byte[len];
Array.Copy(p.buf, index, value, 0, value.Length);
}
CallFunction(conn, p.srcid, p.destid, p.magic, memid, value);
} break;
case Proto.INFO_CALL_FUNCTION_REQUEST_BIGSIZE:
{
Pack_BigSize pack = new Pack_BigSize();
if (!pack.TryParse(p.buf))
return false;
var ts = from t in Transactions where t.Conn == conn && t.Magic == p.magic select t;
Transaction tran;
if (ts.Count() == 0)
{
tran = new Transaction()
{
Conn = conn,
SrcObjID = p.srcid,
Magic = p.magic
};
Transactions.Add(tran);
}
else
{
tran = ts.First();
}
if (!tran.ToBuf(pack))
{
//继续获取参数!!!!!!!!!
SendMessageEx(conn, p.srcid, p.destid, p.magic,
Proto.INFO_PUSH_CALL_FUNCTION_REQUEST_BIGSIZE,null);
}
else
{
Transactions.Remove(tran);//用完了,删除!!!
CallFunction(conn, p.srcid, p.destid, p.magic, tran.FuncID, tran.Buf);
}
}break;
case Proto.INFO_CALL_FUNCTION_REPONSE_BIGSIZE:
{
PushCallFunctionEx_ReponseBigSize(conn, p.srcid, p.destid, p.magic);
}break;
case Proto.INFO_CONFIG_SENSE_OBJ:
{
SENSE_CONFIG action;
if (p.buf[0] == 0)
action = SENSE_CONFIG.ADD;
else
action = SENSE_CONFIG.REMOVE;
UInt32 mask = BitConverter.ToUInt32(p.buf, 1);
Sense_Config(conn, p.srcid, p.destid, mask, action);
} break;
case Proto.INFO_OBJ_DISPOSE:
{
ClearRemoteObjConn(conn, p.srcid);
} break;
}
//DateTime dt1 = DateTime.Now;
//Console.WriteLine("FObjSys ParsePacketInServer " + "p.info=" + p.info.ToString() + " " + (dt1 - dt2).TotalMilliseconds.ToString() + " " + (dt1 - dtlast).TotalMilliseconds.ToString());
//dtlast = dt1;
return true;
}
class Transaction
{
#region 成员变量
public UInt32 SrcObjID;//客户端发起的 源ID
public IFConn Conn;
///
/// 包总大小, -1 ,大小未知
///
public int Size = -1;
public int Position = 0;
///
/// 交易号, 服务器分配的
///
public UInt32 Magic;
///
/// 数据
///
public byte[] Buf;
public object AsyncDelegate;
public object AsyncState;
public UInt16 FuncID;
public const UInt16 PackSize = 0x4000;
#endregion
public Transaction()
{
Size = 0;
Position = 0;
Magic = 0;
Buf = null;
}
byte[] GetBuf()
{
int len = Buf.Length - Position;
if (len > PackSize)
len = PackSize;
byte[] buf = new byte[len];
Array.Copy(Buf, Position, buf, 0, len);
return buf;
}
public bool GetBigSize(out Pack_BigSize p)
{
p = new Pack_BigSize();
p.funcid = FuncID;
p.size = Size;
p.position = Position;
p.buf = GetBuf();
Position += p.buf.Length;
if (Position == Size)
return true;
else
return false;
}
public bool Reset()
{
Buf = null;
Size = -1;
Position = 0;
if ((AsyncDelegate == null) && (AsyncState == null))
{
return true;
}
return false;
}
public bool ToBuf(Pack_BigSize p)
{
if (Buf == null)
{
FuncID = p.funcid;
Size = p.size;
Buf = new byte[Size];
Array.Copy(p.buf, 0, Buf, p.position, p.buf.Length);
Position = p.position + p.buf.Length;
return false;
}
else
{
Array.Copy(p.buf, 0, Buf, p.position, p.buf.Length);
Position = p.position + p.buf.Length;
if (Position == Size)
{
return true;
}
return false;
}
}
}
}
}