public static ExchangeData BiserDecode(byte[] enc = null, Biser.Decoder extDecoder = null)
        {
            Biser.Decoder decoder = null;
            if (extDecoder == null)
            {
                if (enc == null || enc.Length == 0)
                {
                    return(null);
                }
                decoder = new Biser.Decoder(enc);
            }
            else
            {
                if (extDecoder.CheckNull())
                {
                    return(null);
                }
                else
                {
                    decoder = extDecoder;
                }
            }

            ExchangeData m = new ExchangeData();



            m.LastServerSyncTimeStamp = decoder.GetLong();
            m.SyncOperations          = decoder.CheckNull() ? null : new System.Collections.Generic.List <SyncOperation>();
            if (m.SyncOperations != null)
            {
                decoder.GetCollection(() => {
                    var pvar1 = SyncOperation.BiserDecode(null, decoder);
                    return(pvar1);
                }, m.SyncOperations, true);
            }
            m.RepeatSynchro          = decoder.GetBool();
            m.NewServerSyncTimeStamp = decoder.GetLong();


            return(m);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public async Task <ESyncResult> SyncEntity()
        {
            try
            {
                bool repeatSynchro;

                var toServer = new ExchangeData();

                using (var tran = SyncEngine.DBEngine.GetTransaction())
                {
                    toServer.SyncOperations          = this.GetSyncOperations(tran, out repeatSynchro);
                    toServer.LastServerSyncTimeStamp = this.GetLastServerSyncTimeStamp(tran);
                }



                //Sending Entities to server
                //var httpCapsule = await _engine._serverSender("/modules.http.GM_PersonalDevice/IDT_Actions",

                var caps = new HttpCapsule
                {
                    Action     = "SYNC",
                    EntityType = typeof(T).FullName,
                    Body       = toServer.BiserEncoder().Encode()
                };

                var httpCapsuleBt = await SyncEngine._serverSender(_entitySync.urlSync, caps.BiserEncoder().Encode());

                if (httpCapsuleBt == null)  //Synchro with error
                {
                    return(ESyncResult.ERROR);
                }

                var httpCapsule = HttpCapsule.BiserDecode(httpCapsuleBt);

                //if (httpCapsule == null)  //Synchro with error
                //    return ESyncResult.ERROR;

                //Dictionary<string, string> res = httpCapsule.Type.DeserializeJsonSimple();

                if (httpCapsule.IsOk)
                {
                    var exData = ExchangeData.BiserDecode(httpCapsule.Body);

                    if (!repeatSynchro && exData.RepeatSynchro)
                    {
                        repeatSynchro = true;
                    }

                    if (SyncEngine.Verbose)
                    {
                        Console.WriteLine($"SyncEntity<{ typeof(T).Name }> ::: server returned {exData.SyncOperations?.Count} items.");
                    }

                    if (this.UpdateLocalDatabase(exData))
                    {
                        return(await SyncEntity()); //this is a rare exeuting place, only in case if clientSideEntityID equals to existing serverSideEntityID, and even in this case it should be executed only once
                    }
                }
                else if (!httpCapsule.IsOk && httpCapsule.Action == "AUTH FAILED")
                {
                    if (SyncEngine._resetWebSession != null)
                    {
                        try
                        {
                            SyncEngine._resetWebSession?.Invoke();
                        }
                        catch
                        {}
                    }

                    return(ESyncResult.AUTH_FAIL);
                }

                //Repeat call of the procedure
                if (repeatSynchro)
                {
                    return(ESyncResult.REPEAT);
                }
            }
            catch (Exception ex)
            {
                Logger.LogException("EntitySyncingClient.SyncStrategyV1", "SyncEntity", ex, $"type: {typeof(T).Name}");

                return(ESyncResult.ERROR);
            }

            if (SyncEngine.Verbose)
            {
                Console.WriteLine($"SyncEntity<{ typeof(T).Name }> ::: finished");
            }

            return(ESyncResult.OK);
        }
示例#3
0
 public abstract bool UpdateLocalDatabase(ExchangeData exData);
示例#4
0
        public override bool UpdateLocalDatabase(ExchangeData exData) //(List<SyncOperation> syncList, long newServerSyncTimeStamp)
        {
            var  now       = DateTime.UtcNow.Ticks;
            bool reRunSync = false;

            using (var tran = SyncEngine.DBEngine.GetTransaction())
            {
                //Synchronization of all necessary tables must be in entitySync.Init
                _entitySync.tran = tran;
                _entitySync.Init();
                tran.ValuesLazyLoadingIsOn = false;

                tran.Insert(_entitySync.entityTable, new byte[] { LocalSyncTS, 1 }, _newLocalSyncTimeStamp > exData.NewServerSyncTimeStamp ? _newLocalSyncTimeStamp : exData.NewServerSyncTimeStamp);
                tran.Insert(_entitySync.entityTable, new byte[] { ServerSyncTS, 2 }, exData.NewServerSyncTimeStamp);
                T entity;
                T localEntity;

                int processedBeforeRaise = 0;

                //Taking care changed IDs by server
                foreach (var opr in exData.SyncOperations.Where(r => r.Operation == SyncOperation.eOperation.EXCHANGE))
                {
                    if (opr.ExternalId > 0)
                    {
                        //opr.ExternalID will help to determine new ID
                        var rowLocalEntity = tran.Select <byte[], byte[]>(_entitySync.entityTable, new byte[] { Entity }.Concat(opr.InternalId.To_8_bytes_array_BigEndian()));
                        if (rowLocalEntity.Exists)
                        {
                            var oldEntity = rowLocalEntity.GetDataBlockWithFixedAddress <T>();

                            _entitySync.ptrContent = null;

                            //New GeneratedID must be stored for the new sync
                            ((ISyncEntity)oldEntity).Id            = opr.ExternalId; //Theoretically on this place can be called a user-function to get another ID type
                            ((ISyncEntity)oldEntity).SyncTimestamp = ++now;          //must be returned back, overriding SyncTimeStamp

                            _entitySync.OnInsertEntity(oldEntity, default(T), SyncEngine.Serialize(oldEntity), opr.InternalId);

                            InsertIndex4Sync(tran, _entitySync.entityTable, oldEntity, _entitySync.ptrContent, default(T));


                            //Setting value from the server for the existing ID (real entity that must belong to that id)
                            _entitySync.ptrContent = rowLocalEntity.Value;

                            _entitySync.OnInsertEntity((T)SyncEngine.Deserialize(opr.SerializedObject, typeof(T)), default(T),
                                                       opr.SerializedObject, 0);

                            reRunSync = true;
                        }
                    }
                }

                //standard entites
                foreach (var opr in exData.SyncOperations.Where(r => r.Operation != SyncOperation.eOperation.EXCHANGE))
                {
                    switch (opr.Operation)
                    {
                    case SyncOperation.eOperation.INSERT:
                        var rowLocalEntity = tran.Select <byte[], byte[]>(_entitySync.entityTable, new byte[] { Entity }.Concat(opr.InternalId.To_8_bytes_array_BigEndian()));
                        if (rowLocalEntity.Exists)
                        {
                            //Possible update
                            _entitySync.ptrContent = rowLocalEntity.Value;
                            localEntity            = rowLocalEntity.GetDataBlockWithFixedAddress <T>();

                            entity = (T)SyncEngine.Deserialize(opr.SerializedObject, typeof(T));

                            if (((ISyncEntity)localEntity).SyncTimestamp < opr.SyncTimestamp)
                            {
                                //Local version is weaker then server version
                                _entitySync.OnInsertEntity(entity, localEntity, opr.SerializedObject, 0);

                                InsertIndex4Sync(tran, _entitySync.entityTable, entity, _entitySync.ptrContent, localEntity);
                            }
                            else
                            {
                                ////------------Nothing
                            }
                        }
                        else
                        {
                            //Inserting new entity from server
                            _entitySync.ptrContent = null;
                            // entity = opr.SerializedObject.DeserializeProtobuf<T>();
                            entity = (T)SyncEngine.Deserialize(opr.SerializedObject, typeof(T));

                            _entitySync.OnInsertEntity(entity, default(T), opr.SerializedObject, 0);
                            InsertIndex4Sync(tran, _entitySync.entityTable, entity, _entitySync.ptrContent, default(T));
                        }
                        break;

                    case SyncOperation.eOperation.REMOVE:

                        //------------DOING NOTHING, WE DONT DELETE ENTITIES

                        break;
                    }

                    //Computing processed elements and raises event once per SyncEntitiesMgr.RaiseSyncProcessEach
                    System.Threading.Interlocked.Increment(ref Engine.SyncOperationsCount);
                    processedBeforeRaise++;
                    if (processedBeforeRaise >= Engine.RaiseSyncProcessEach)
                    {
                        processedBeforeRaise = 0;
                        Engine.OnSyncProcess();
                    }
                }

                _entitySync.BeforeCommit();

                tran.Commit();
            }
            _entitySync.OnEntitySyncIsFinished();

            return(reRunSync);
        }