using System; using System.Collections.Generic; using System.Linq; using System.Text; using FObjBase; using System.ComponentModel; using System.Collections.Specialized; namespace FLY.Thick.BulkDataModule { public class BulkDataServiceClient : FObjServiceClient, INotifyPropertyChanged,IBulkDataService { #region IBulkDataService class DataRequest { public object Param; public object AsyncState; public AsyncCBHandler AsyncDelegate; public override bool Equals(object obj) { if (!(obj is DataRequest)) return false; DataRequest dr = obj as DataRequest; if (!AsyncState.Equals(dr.AsyncState)) return false; if (!IsSameParam(Param, dr.Param)) return false; return true; } bool IsSameParam_PushNewFrameData(object src, object dest) { if ((src is BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam) && (dest is BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam)) { BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam fdparam = src as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam; BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam cfdparam = dest as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam; if (fdparam.mix == cfdparam.mix) { return true; } else { return false; } } return false; } bool IsSameParam_GetFrameData(object src, object dest) { if ((src is BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData) && (dest is BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData)) { BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData fdparam = src as BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData; BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData cfdparam = dest as BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData; if ((fdparam.bm == cfdparam.bm) && (fdparam.mix == cfdparam.mix)) { return true; } else { return false; } } return false; } bool IsSameParam_GetTrendData(object src, object dest) { if ((src is BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData) && (dest is BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData)) { BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData tdparam = src as BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData; BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData ctdparam = dest as BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData; if ((tdparam.mix == ctdparam.mix) && (tdparam.fromBoltNo == ctdparam.fromBoltNo) && (tdparam.toBoltNo == ctdparam.toBoltNo)) { return true; } else { return false; } } return false; } bool IsSameParam_GetFrameDataMix(object src, object dest) { if ((src is Pack_CallClosePushFrameDataMixRequest) && (dest is Pack_CallClosePushFrameDataMixRequest)) { return ((Pack_CallClosePushFrameDataMixRequest)src).IsSame( dest as Pack_CallClosePushFrameDataMixRequest); } return false; } public bool IsSameParam(object src, object dest) { if (IsSameParam_GetFrameData(src, dest) == true) return true; if (IsSameParam_GetTrendData(src, dest) == true) return true; if (IsSameParam_PushNewFrameData(src, dest) == true) return true; if (IsSameParam_GetFrameDataMix(src, dest) == true) return true; return false; } } List dataRequestList = new List(); #endregion #region 缓冲区 private List m_fr_data = new List(); public List Datas { get { return m_fr_data; } } public event NotifyDatasChangedEventHandler DatasChanged; /// /// 数量 /// public int Count { get; set; } /// /// 最新的bookmark /// public int CurrentBookmark { get; set; } = -1; /// /// 分区数 /// public int NBolts { get; protected set; } = 80; /// /// 第1分区号 /// public int BoltNo1st { get; protected set; } #endregion /// /// /// /// public BulkDataServiceClient(UInt32 serviceId) : base(serviceId) { this.PropertyChanged += BulkDataServiceClient_PropertyChanged; } public BulkDataServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { this.PropertyChanged += BulkDataServiceClient_PropertyChanged; } private void BulkDataServiceClient_PropertyChanged(object sender, PropertyChangedEventArgs e) { if ((e.PropertyName == "Count")||(e.PropertyName == "CurrentBookmark")) { if (Datas.Count() > Count) { Datas.RemoveRange(0, Datas.Count() - Count); } } } #region IBulkDataService public void GetFrameData(BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState) { CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_GET_FRAMEDATA, param.ToBytes());//自己管理 AsyncDelegate, 不使用ObjSys 的 DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState, AsyncDelegate = AsyncDelegate }; if (!dataRequestList.Exists(_dr => _dr.Equals(dr))) { dataRequestList.Add(dr); } } public void ClosePushFrameData(BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData param, object AsyncState) { FObjSys.Current.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_CLOSE_PUSH_FRAMEDATA, param.ToBytes()); DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState }; dataRequestList.Remove(dr); } public void GetTrendData(BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState) { CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_GET_TRENDDATA, param.ToBytes());//自己管理 AsyncDelegate, 不使用ObjSys 的 DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState, AsyncDelegate = AsyncDelegate }; if (!dataRequestList.Exists(_dr => _dr.Equals(dr))) { dataRequestList.Add(dr); } } public void ClosePushTrendData(BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData param, object AsyncState) { FObjSys.Current.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_CLOSE_PUSH_TRENDDATA, param.ToBytes()); DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState }; dataRequestList.Remove(dr); } public void PushNewFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState) { CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_PUSH_NEWFRAMEDATA, param.ToBytes());//自己管理 AsyncDelegate, 不使用ObjSys 的 DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState, AsyncDelegate = AsyncDelegate }; if (!dataRequestList.Exists(_dr => _dr.Equals(dr))) { dataRequestList.Add(dr); } } public void ClosePushNewFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallClosePushNewFrameData param, object AsyncState) { FObjSys.Current.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_CLOSE_PUSH_NEWFRAMEDATA, param.ToBytes()); DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState }; dataRequestList.Remove(dr); } public void GetFrameDataMix(Pack_CallGetFrameDataMixRequest param, AsyncCBHandler AsyncDelegate, object AsyncState) { CurrObjSys.CallFunctionEx(mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_GET_FRAMEDATAMIX, param.ToBytes());//自己管理 AsyncDelegate, 不使用ObjSys 的 DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState, AsyncDelegate = AsyncDelegate }; if (!dataRequestList.Exists(_dr => _dr.Equals(dr))) { dataRequestList.Add(dr); } } public void ClosePushFrameDataMix(Pack_CallClosePushFrameDataMixRequest param, object AsyncState) { FObjSys.Current.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_CLOSE_PUSH_FRAMEDATAMIX, param.ToBytes()); DataRequest dr = new DataRequest() { Param = param, AsyncState = AsyncState }; dataRequestList.Remove(dr); } public void Clear() { FObjSys.Current.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_CLEAR, null); } /// /// 只要关于AsyncState 的都要删除 /// /// public void ClosePush(Predicate match) { dataRequestList.RemoveAll(delegate(DataRequest dr) { return match(dr.AsyncState); }); } #endregion #region FObj public override void ConnectNotify(IFConn from) { base.ConnectNotify(from); if (!from.IsConnected) { //连接断开,删除全部!!! dataRequestList.Clear(); } else { Datas.Clear(); CurrentBookmark = -1; Count = 0; CurrObjSys.GetValueEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.GET_PARAMS); CurrObjSys.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_GET_LIST_NEW_10, null); CurrObjSys.CallFunctionEx( mConn, mServerID, ID, BULKDATA_OBJ_INTERFACE.CALL_GET_LIST_OTHER, null); CurrObjSys.SenseConfigEx( mConn, mServerID, ID, 0xffffffff, SENSE_CONFIG.ADD); } } public override void PushCallFunction(IFConn from, UInt32 srcid, UInt32 magic, UInt16 funcid, byte[] retdata, object AsyncDelegate, object AsyncState) { switch (funcid) { case BULKDATA_OBJ_INTERFACE.CALL_PUSH_NEWFRAMEDATA: { BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn reponse = new BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn(); if (!reponse.TryParse(retdata)) return; //当为push时,没有AsyncDelegate,AsyncState List drs = dataRequestList.FindAll(dr => dr.IsSameParam(dr.Param, reponse)); foreach (DataRequest dr in drs) { dr.AsyncDelegate(dr.AsyncState, reponse); } }break; case BULKDATA_OBJ_INTERFACE.CALL_GET_FRAMEDATA: { BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn reponse = new BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn(); if (!reponse.TryParse(retdata)) return; //当为push时,没有AsyncDelegate,AsyncState List drs = dataRequestList.FindAll(dr => dr.IsSameParam(dr.Param, reponse)); foreach (DataRequest dr in drs) { dr.AsyncDelegate(dr.AsyncState, reponse); } } break; case BULKDATA_OBJ_INTERFACE.CALL_GET_TRENDDATA: { BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn reponse = new BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn(); if (!reponse.TryParse(retdata)) return; List drs = dataRequestList.FindAll(dr => dr.IsSameParam(dr.Param, reponse)); foreach (DataRequest dr in drs) { dr.AsyncDelegate(dr.AsyncState, reponse); } } break; case BULKDATA_OBJ_INTERFACE.CALL_GET_FRAMEDATAMIX: { Pack_CallGetFrameDataMixReponse reponse = new Pack_CallGetFrameDataMixReponse(); if (!reponse.TryParse(retdata)) return; //当为push时,没有AsyncDelegate,AsyncState List drs = dataRequestList.FindAll(dr => dr.IsSameParam(dr.Param, reponse)); foreach (DataRequest dr in drs) { dr.AsyncDelegate(dr.AsyncState, reponse); } } break; case BULKDATA_OBJ_INTERFACE.CALL_GET_LIST_NEW_10: { BULKDATA_OBJ_INTERFACE.Pack_CallGetListReponse p = new BULKDATA_OBJ_INTERFACE.Pack_CallGetListReponse(); if (!p.TryParse(retdata)) return; AddList(p.list); } break; case BULKDATA_OBJ_INTERFACE.CALL_GET_LIST_OTHER: { BULKDATA_OBJ_INTERFACE.Pack_CallGetListReponse p = new BULKDATA_OBJ_INTERFACE.Pack_CallGetListReponse(); if (!p.TryParse(retdata)) return; AddList(p.list); } break; } } public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata) { switch (memid) { case BULKDATA_OBJ_INTERFACE.GET_PARAMS: { BULKDATA_OBJ_INTERFACE.Pack_Params p = new BULKDATA_OBJ_INTERFACE.Pack_Params(); if (!p.TryParse(infodata)) return; Count = p.count; CurrentBookmark = p.currentbookmark; NBolts = p.nbolts; BoltNo1st = p.boltNo1st; } break; } } public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata) { switch (infoid) { case BULKDATA_OBJ_INTERFACE.PUSH_PARAMS: { PushGetValue(from, srcid, BULKDATA_OBJ_INTERFACE.GET_PARAMS, infodata); }break; case BULKDATA_OBJ_INTERFACE.PUSH_CHANGED: { BULKDATA_OBJ_INTERFACE.Pack_PushChanged p = new BULKDATA_OBJ_INTERFACE.Pack_PushChanged(); if (!p.TryParse(infodata)) return; AddList(p.data); } break; } } #endregion void AddList(List datas) { if (Datas.Count == 0) { //没有数据,肯定插入到尾 Datas.AddRange(datas); DatasChanged?.Invoke( this, new NotifyDatasChangedEventArgs() { Action = NotifyDatasChangedAction.Add, Items = datas, NewStartingIndex = 0 }); } else { //原来已经有数据,肯定插入到头 Datas.InsertRange(0, datas); DatasChanged?.Invoke( this, new NotifyDatasChangedEventArgs() { Action = NotifyDatasChangedAction.Add, Items = datas, NewStartingIndex = 0 }); } } void AddList(FR_DATA data) { if (data == null) { Datas.Clear(); DatasChanged?.Invoke( this, new NotifyDatasChangedEventArgs() { Action = NotifyDatasChangedAction.Reset }); return; } int idx = Datas.FindIndex(d => { return d.bookmark == data.bookmark; }); if (idx == -1) { //添加 Datas.Add(data); DatasChanged?.Invoke( this, new NotifyDatasChangedEventArgs() { Action = NotifyDatasChangedAction.Add, Items = new List(new FR_DATA[] { data}), NewStartingIndex = Datas.Count()-1 }); } else { //修改 Datas[idx] = data; DatasChanged?.Invoke( this, new NotifyDatasChangedEventArgs() { Action = NotifyDatasChangedAction.Replace, Items = new List(new FR_DATA[] { data }), NewStartingIndex = idx }); } } } }