예제 #1
0
        public bool ChangeReceived(string sessionKey, int clientRevisionId, string selStr, string changeStr)
        {
            try
            {
                lock (lockObject)
                {
                    var sess = sessions.Find(x => x.SessionKey == sessionKey);
                    if (sess == null)
                    {
                        return(false);
                    }
                    sess.LastActiveUtc = DateTime.UtcNow;
                    ensureDocLoaded(sess.DocId);
                    var doc = docs.Find(x => x.DocId == sess.DocId);
                    if (doc == null)
                    {
                        return(false);
                    }
                    var       sel = JsonConvert.DeserializeObject <Selection>(selStr);
                    ChangeSet cs  = changeStr != null?ChangeSet.FromJson(changeStr) : null;

                    logger.Verbose("Change received from session {sessionKey}: client rev {clientRevisionId}, sel: {sel} , change: \n{change}",
                                   sessionKey, clientRevisionId, selStr, changeStr);

                    // Who are we broadcasting to?
                    List <string> receivers = new List <string>();
                    foreach (var x in sessions)
                    {
                        if (x.RequestedUtc == DateTime.MinValue && x.DocId == doc.DocId)
                        {
                            receivers.Add(x.SessionKey);
                        }
                    }

                    // What are we broadcasting?
                    ChangeToBroadcast ctb = new ChangeToBroadcast
                    {
                        SourceSessionKey        = sessionKey,
                        SourceBaseDocRevisionId = clientRevisionId,
                        NewDocRevisionId        = doc.Revisions.Count - 1,
                        ReceiverSessionKeys     = receivers,
                    };
                    // This is only about a changed selection
                    if (cs == null)
                    {
                        sess.Selection = doc.ForwardSelection(sel, clientRevisionId);
                        ctb.SelJson    = JsonConvert.SerializeObject(getDocSels(sess.DocId));
                        logger.Verbose("Propagating selection update: {sels}", ctb.SelJson);
                    }
                    // We got us a real change set
                    else
                    {
                        if (!cs.IsValid())
                        {
                            logger.Warning("Change is invalid. Ending this session.");
                            return(false);
                        }
                        ChangeSet csToProp;
                        doc.ApplyChange(cs, sel, clientRevisionId, out csToProp, out sess.Selection);
                        ctb.NewDocRevisionId = doc.Revisions.Count - 1;
                        ctb.SelJson          = JsonConvert.SerializeObject(getDocSels(sess.DocId));
                        ctb.ChangeJson       = csToProp.SerializeJson();
                        logger.Verbose("Propagating changeset and selection update:\n{change}\n{sels}", ctb.ChangeJson, ctb.SelJson);
                    }
                    // Showtime!
                    Broadcaster.EnqueueChangeForBroadcast(ctb);
                }
                return(true);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error in ChangeReceived");
                throw;
            }
        }