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 } /// <summary> /// 建议使用方法: /// 做为客户端,都使用 FObjSys.Current 连接不同的客户端 /// 做为服务器,当要提供2个Obj服务, 应该要使用 Currents[index] /// 这套逻辑已经潜入到 每个 FObj 中, FObj.CurrObjSys, 就是对应的 Obj服务 /// </summary> public class FObjSys : IFObjSysAsClient, IFObjSysAsServer { public static FObjSys Current; public static List<FObjSys> Currents = new List<FObjSys>(); TCPListen m_tcplisten; Dictionary<TCPCConn, List<UInt32>> m_cconns = new Dictionary<TCPCConn, List<UInt32>>();//管理连接到异地服务器的连接 List<UInt32> m_serverConnectedNotifyObjID = new List<UInt32>();//作为服务器,当客户端断开,发送通知 /// <summary> /// 交易列表 /// </summary> List<Transaction> Transactions = new List<Transaction>(); /// <summary> /// 消息推送的敏感对象 /// </summary> class Sense { public IFConn conn; public UInt32 objid; public UInt32 sense_mask; //public bool hasPush; } Dictionary<IFObj, List<Sense>> Objs = new Dictionary<IFObj, List<Sense>>(); static FObjSys() { Currents.Add(new FObjBase.FObjSys()); Current = Currents[0]; } public FObjSys() { } #region IFObjSys /// <summary> /// 添加OBJ到系统 /// </summary> /// <param name="obj"></param> public void ObjAdd(IFObj obj) { if (obj.ID == 0) obj.ID = GetFreeObjID(); Objs.Add(obj, new List<Sense>()); } /// <summary> /// 对外发送消息 /// </summary> /// <param name="s1">远端对应的连接代理 </param> /// <param name="destid">远端的ID</param> /// <param name="srcid">本地的ID</param> /// <param name="magic">交易码</param> /// <param name="info_no">信息码</param> /// <param name="info_data">信息内容</param> 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; } /// <summary> /// 指定推送到某个远端 /// </summary> /// <param name="srcobj"></param> /// <param name="infoid"></param> /// <param name="infodata"></param> /// <param name="s1"></param> /// <param name="destid"></param> 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<byte> buf = new List<byte>(); buf.AddRange(BitConverter.GetBytes(infoid)); buf.AddRange(infodata); SendMessageEx(s1, destid, srcobj.ID, 0x1234, Proto.INFO_PUSH_EVENT, buf.ToArray()); } /// <summary> /// 推送到远端,系统判定根据敏感对象推送 /// </summary> /// <param name="srcobj"></param> /// <param name="infoid"></param> /// <param name="infodata"></param> public void PushObjInfoEx(IFObj srcobj, UInt16 infoid, byte[] infodata) { if (!Objs.Keys.Contains(srcobj)) return; List<Sense> 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<byte> buf = new List<byte>(); 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; } } } /// <summary> /// 推送到远端,系统判定根据敏感对象推送,但不推送给特定某对象 /// </summary> /// <param name="srcobj"></param> /// <param name="infoid"></param> /// <param name="infodata"></param> /// <param name="except_s1"></param> /// <param name="except_destid"></param> public void PushObjInfoEx_except(IFObj srcobj, UInt16 infoid, byte[] infodata, IFConn except_s1, UInt32 except_destid) { if (!Objs.Keys.Contains(srcobj)) return; List<Sense> 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<byte> buf = new List<byte>(); 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; } } } /// <summary> /// 回复 客户端的CallFunction /// </summary> /// <param name="s1">客户端对应的连接代理 </param> /// <param name="destid">客户端的对象ID</param> /// <param name="srcid">本地服务端的对象ID</param> /// <param name="magic">交易码</param> /// <param name="funcid">函数ID</param> /// <param name="param">函数返回</param> 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 客户端 /// <summary> /// 获取没用使用的OBJID /// </summary> /// <returns></returns> public UInt32 GetFreeObjID() { if (Objs.Count > 0) return Objs.Max(obj => obj.Key.ID) + 1; else return 1; } /// <summary> /// 从系统删除OBJ /// </summary> /// <param name="obj"></param> public void ObjRemove(IFObj obj) { Objs.Remove(obj);//作为服务端,关闭推送服务 foreach (var kv in m_cconns) { kv.Value.Remove(obj.ID); } } /// <summary> /// 作为客户端,从系统删除OBJ; /// 还会通知服务器,断开与这个 OBJ 的所有连接 /// </summary> /// <param name="obj"></param> /// <param name="conn"></param> 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); } } /// <summary> /// 连接到远端的OBJSys连接 /// </summary> /// <param name="ep">远端地址</param> /// <param name="objids">连接成功后,通知这些obj</param> /// <returns></returns> public TCPCConn Connect_to_Another_OBJSys(IPEndPoint ep, params UInt32[] objids) { try { KeyValuePair<TCPCConn, List<UInt32>> 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<uint>(objids)); return conn; } } /// <summary> /// 断开到远端OBJSys的连接 /// </summary> /// <param name="ep">远端地址</param> /// <param name="objids">连接成功后,通知这些obj</param> /// <returns></returns> public void Disconnect_to_Another_OBJSys(IPEndPoint ep, params UInt32[] objids) { try { KeyValuePair<TCPCConn, List<UInt32>> 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 { } } /// <summary> /// 注册本地obj 为远端obj的敏感对象,得到远端obj的推送消息 /// </summary> /// <param name="s1">远端对应的连接代理 </param> /// <param name="objid">远端的ID</param> /// <param name="senobjid">本地obj</param> /// <param name="sense_mask">注册的敏感源</param> /// <param name="action">动作,添加?删除?</param> public void SenseConfigEx(IFConn s1, UInt32 objid, UInt32 senobjid, UInt32 sense_mask, SENSE_CONFIG action) { if (s1 == null) return; List<byte> buf = new List<byte>(); 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()); } /// <summary> /// 向远端GetValue /// </summary> /// <param name="s1">远端对应的连接代理</param> /// <param name="destid">远端的ID</param> /// <param name="srcid">本地的ID</param> /// <param name="memid">成员ID</param> 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)); } } /// <summary> /// 向远端SetValue /// </summary> /// <param name="s1">远端对应的连接代理</param> /// <param name="destid">远端的ID</param> /// <param name="srcid">本地的ID</param> /// <param name="memid">成员ID</param> /// <param name="value">成员内容</param> 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<byte> buf = new List<byte>(); buf.AddRange(BitConverter.GetBytes(memid)); buf.AddRange(value); UInt32 magic = GetFreeMagic(); SendMessageEx(s1, destid, srcid, magic, Proto.INFO_SET_VALUE, buf.ToArray()); return; } /// <summary> /// 向远端CallFunction /// </summary> /// <param name="s1">远端对应的连接代理 </param> /// <param name="destid">远端对象ID</param> /// <param name="srcid">本地对象ID</param> /// <param name="funcid">函数ID</param> /// <param name="param">函数参数</param> /// <param name="AsyncDelegate">在其上调用异步调用的委托对象</param> /// <param name="AsyncState">作为 BeginInvoke 方法调用的最后一个参数而提供的对象</param> 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; } } /// <summary> /// 向远端CallFunction /// </summary> /// <param name="s1">远端对应的连接代理 </param> /// <param name="destid">远端对象ID</param> /// <param name="srcid">本地对象ID</param> /// <param name="funcid">函数ID</param> /// <param name="param">函数参数</param> 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 /// <summary> /// 通过objid 查找 obj /// </summary> /// <param name="objid"></param> /// <returns></returns> IFObj Find(UInt32 objid) { try { KeyValuePair<IFObj, List<Sense>> obj_kv = Objs.First(obj => obj.Key.ID == objid); return obj_kv.Key; } catch { return null; } } UInt32 free_magic = 1; /// <summary> /// 获取一个没有被分配的 交易码 /// </summary> /// <returns></returns> UInt32 GetFreeMagic() { UInt32 f = free_magic; free_magic++; if (free_magic == 0) free_magic++; //if (free_magic > UInt32.MaxValue) // freetranno = 1; return f; } /// <summary> /// 作为客户端,与服务器连续状态改变 /// </summary> /// <param name="conn"></param> void CConnConnectAction(IFConn conn) { TCPCConn cc = (TCPCConn)conn; KeyValuePair<TCPCConn, List<UInt32>> 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 { } } /// <summary> /// 作为服务器端,客户的登陆与退出 /// </summary> /// <param name="conn"></param> 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<Sense> senses = Objs.ElementAt(i).Value; senses.RemoveAll(s => s.conn == conn); } //删除所有与它有关的 tran Transactions.RemoveAll(t => t.Conn == conn); } } /// <summary> /// 作为服务器端,客户端 的 某obj 注销了,把它相关的都删除 /// </summary> /// <param name="conn"></param> /// <param name="srcid"></param> void ClearRemoteObjConn(IFConn conn, UInt32 srcid) { //删除推送 for (int i = 0; i < Objs.Keys.Count(); i++) { List<Sense> 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的函数指针 /// <summary> /// 本地,给Protocol的函数指针; /// GetValue /// </summary> /// <param name="from">远端对应的连接代理</param> /// <param name="srcid">远端对象ID</param> /// <param name="destid">本地对象ID</param> /// <param name="memid"></param> /// <param name="value"></param> /// <returns></returns> 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); } /// <summary> /// 本地,给Protocol的函数指针; /// SetValue /// </summary> /// <param name="from">远端对应的连接代理</param> /// <param name="srcid">远端对象ID</param> /// <param name="destid">本地对象ID</param> /// <param name="memid"></param> /// <param name="value"></param> 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); } /// <summary> /// 本地,给Protocol的函数指针; /// CallFunction /// </summary> /// <param name="from">远端对应的连接代理</param> /// <param name="srcid">远端对象ID</param> /// <param name="destid">本地对象ID</param> /// <param name="funcid"></param> /// <param name="param"></param> /// <param name="ret"></param> /// <returns></returns> 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); } /// <summary> /// 本地,给Protocol的函数指针; /// Sense_Config /// </summary> /// <param name="from">远端对应的连接代理</param> /// <param name="srcid">远端对象ID</param> /// <param name="destid">本地对象ID</param> /// <param name="sense_mask">远端对象 关注 本地对象 的敏感源</param> /// <param name="action">动作,添加?删除?</param> void Sense_Config(IFConn from, UInt32 srcid, UInt32 destid, UInt32 sense_mask, SENSE_CONFIG action) { try { KeyValuePair<IFObj, List<Sense>> 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; /// <summary> /// 从异端接收的数据,解释数据 /// </summary> /// <param name="packet"></param> /// <param name="conn"></param> /// <returns></returns> 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; } /// <summary> /// 从异端接收的数据,解释数据 /// </summary> /// <param name="packet"></param> /// <param name="conn"></param> /// <returns></returns> 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<byte> buf = new List<byte>(); 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; /// <summary> /// 包总大小, -1 ,大小未知 /// </summary> public int Size = -1; public int Position = 0; /// <summary> /// 交易号, 服务器分配的 /// </summary> public UInt32 Magic; /// <summary> /// 数据 /// </summary> 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; } } } } }