private void HandleMessage(JObject msg)
        {
            ShareDBException ex = null;
            var error           = (JObject)msg["error"];

            if (error != null)
            {
                ex = new ShareDBException((string)error["message"], (int)error["code"]);
            }

            IDocumentInternal doc;

            switch ((string)msg["a"])
            {
            case "init":
                if ((int)msg["protocol"] != 1)
                {
                    _initTcs.SetException(new ShareDBException("Invalid protocol version.", 4019));
                    return;
                }
                if ((string)msg["type"] != "http://sharejs.org/types/JSONv0")
                {
                    _initTcs.SetException(new ShareDBException("Invalid default type.", 4020));
                    return;
                }
                if (msg["id"].Type != JTokenType.String)
                {
                    _initTcs.SetException(new ShareDBException("Invalid client id.", 4021));
                    return;
                }

                _id = (string)msg["id"];
                _initTcs.SetResult(true);
                break;

            case "f":
                doc = GetExisting((string)msg["c"], (string)msg["d"]);
                var snapshot = (JObject)msg["data"];
                doc.HandleFetch(ex, (int?)snapshot?["v"] ?? 0, (string)snapshot?["type"], snapshot?["data"]);
                break;

            case "op":
                doc = GetExisting((string)msg["c"], (string)msg["d"]);
                doc.HandleOp(ex, (int?)msg["v"] ?? 0, (int?)msg["seq"] ?? 0);
                break;
            }
        }
Exemple #2
0
        void IDocumentInternal.HandleOp(ShareDBException ex, int version, int seq)
        {
            OpInfo opInfo = _inflightOpInfo;

            _inflightOpInfo = null;
            if (ex != null)
            {
                if (ex.Code == 4002)
                {
                    _inflightOp.SetResult(false);
                }
                else
                {
                    _inflightOp.SetException(ex);
                }
            }
            else if (seq != opInfo.Seq || (opInfo.MessageType != OpMessageType.Create && version != Version))
            {
                _inflightOp.SetException(new ShareDBException("Received incorrect op acknowledgement.", 4100));
            }
            else
            {
                switch (opInfo.MessageType)
                {
                case OpMessageType.Create:
                    Version  = version;
                    Data     = (T)Type.Deserialize(opInfo.Op);
                    IsLoaded = true;
                    break;

                case OpMessageType.Op:
                    Data     = (T)Type.Apply(Data, opInfo.Op);
                    IsLoaded = true;
                    break;

                case OpMessageType.Delete:
                    Data     = default(T);
                    IsLoaded = false;
                    break;
                }

                Version++;
                _inflightOp.SetResult(true);
            }
        }
Exemple #3
0
        void IDocumentInternal.HandleFetch(ShareDBException ex, int version, string type, JToken ops)
        {
            if (!_inflightFetches.TryDequeue(out TaskCompletionSource <bool> tcs))
            {
                return;
            }

            if (ex != null)
            {
                tcs.SetException(ex);
            }
            else
            {
                IOTType otType = null;
                if (type != null && !OTTypes.TryGetType(type, out otType))
                {
                    tcs.SetException(new ShareDBException($"Unregistered type {type}.", 4008));
                }
                if (Type == null)
                {
                    Type = otType;
                }

                if (otType != null && Type != otType)
                {
                    tcs.SetException(new ShareDBException("The document type does not match the retrieved data type.",
                                                          4101));
                }
                else
                {
                    Version = version;
                    if (ops != null)
                    {
                        Data     = (T)Type.Deserialize(ops);
                        IsLoaded = true;
                        tcs.SetResult(true);
                    }
                    else
                    {
                        tcs.SetResult(false);
                    }
                }
            }
        }