public Factory <ExampleClass> .MessagePacket ReceiveMessage(Factory <ExampleClass> .MessagePacket clientMsg) { if (!ExampleSyncers.ContainsKey(clientMsg.ObjectGuid)) { ExampleSyncers.Add(clientMsg.ObjectGuid, new Dictionary <Guid, Factory <ExampleClass> .Syncer>()); } ExampleClass live, shadow = new ExampleClass() { Guid = clientMsg.ObjectGuid }; if (ExampleDB.ContainsKey(clientMsg.ObjectGuid)) { var itemRevs = ExampleDB[clientMsg.ObjectGuid]; var maxRev = itemRevs.Keys.Max(); var latestRev = itemRevs[maxRev]; // Revision = 0 means it's the first upload, yet we have the item. This can happen if a message gets lost; the client doesn't know the server got the message if (clientMsg.Revision != 0) { if (!ExampleDBByRevision.ContainsKey(clientMsg.Revision)) { return new Factory <ExampleClass> .MessagePacket(clientMsg.SessionGuid, clientMsg.ObjectGuid, null) { ClientCompleted = true, ServerError = new Exception("Could not find the given revision #") } } ; // We don't need to start from an existing shadow if the client's base version is empty (and it is likely we have a session with a good shadow already) var baseRev = ExampleDBByRevision[clientMsg.Revision]; // Very important to use this as the common start point shadow = baseRev; } live = latestRev; } else { // No syncer, no item; new item live = new ExampleClass() { Guid = clientMsg.ObjectGuid }; } if (!ExampleSyncers[clientMsg.ObjectGuid].ContainsKey(clientMsg.SessionGuid)) { // No syncer if (clientMsg.Message.SenderPeerVersion != 0) // This could be because of a very old syncer that we discarded? May need to account for obsolete syncers here. { return new Factory <ExampleClass> .MessagePacket(clientMsg.SessionGuid, clientMsg.ObjectGuid, null) { ClientCompleted = true, ServerError = new Exception("The SenderPeerVersion for a new syncer is not 0") } } ; var syncer = Factory <ExampleClass> .Create(clientMsg.ObjectGuid, live.Clone(), shadow.Clone()); syncer.ObjectGuid = clientMsg.ObjectGuid; syncer.SessionGuid = clientMsg.SessionGuid; ExampleSyncers[clientMsg.ObjectGuid].Add(clientMsg.SessionGuid, syncer); } { // Syncer exists (now) var syncer = ExampleSyncers[clientMsg.ObjectGuid][clientMsg.SessionGuid]; syncer.Live.StateObject.SetStateData(live.Clone()); var changed = syncer.ReadMessageCycle(clientMsg.Message); if (changed) { syncer.LiveObject.Revision = NextExampleDBRevisionID++; var newRec = syncer.Live.StateObject.GetStateData(); if (!ExampleDB.ContainsKey(clientMsg.ObjectGuid)) { ExampleDB.Add(clientMsg.ObjectGuid, new Dictionary <int, ExampleClass>()); } if (ExampleDB[clientMsg.ObjectGuid].ContainsKey(newRec.Revision)) { throw new Exception("Database already contains revision being entered."); } if (ExampleDBByRevision.ContainsKey(newRec.Revision)) { throw new Exception("Database already contains revision being entered."); } ExampleDB[clientMsg.ObjectGuid].Add(newRec.Revision, newRec); ExampleDBByRevision.Add(newRec.Revision, newRec); } var msg = syncer.MakeMessageCycle(clientMsg.Message); return(new Factory <ExampleClass> .MessagePacket(clientMsg.SessionGuid, clientMsg.ObjectGuid, msg)); } } }