示例#1
0
        public void Handle(Message message)
        {
            if (message.GetPropertyObjectID == null)
            {
                throw new ArgumentNullException("GetPropertyObjectID is null");
            }

            var entry = this.m_ObjectStorage.Find(message.GetPropertyObjectID).FirstOrDefault();

            if (entry == null)
            {
                throw new InvalidOperationException("Get property message received but we don't own the object!");
            }

            var obj = entry.Value;

            var mi = obj.GetType().GetMethod("get_" + message.GetPropertyPropertyName + "__Distributed0", BindingFlagsCombined.All);

            if (mi == null)
            {
                throw new MissingMethodException(
                          obj.GetType().FullName,
                          "get_" + message.GetPropertyPropertyName + "__Distributed0");
            }

            var value = DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, new Type[0], new object[] { });

            var client = this.m_ClientLookup.Lookup(message.Sender.IPEndPoint);

            client.Send(this.m_MessageConstructor.ConstructGetPropertyResultMessage(message.ID, value));
        }
示例#2
0
        public void Handle(Message message)
        {
            var entry = this.m_ObjectStorage.Find(message.SetPropertyObjectID).FirstOrDefault();

            if (entry == null)
            {
                throw new InvalidOperationException("Set property message received but we don't own the object!");
            }

            var obj = entry.Value;

            var mi = obj.GetType().GetMethod("set_" + message.SetPropertyPropertyName + "__Distributed0", BindingFlagsCombined.All);

            if (mi == null)
            {
                throw new MissingMethodException(obj.GetType().FullName, "set_" + message.SetPropertyPropertyName + "__Distributed0");
            }

            var value = this.m_ObjectWithTypeSerializer.Deserialize(message.SetPropertyPropertyValue);

            DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, new Type[0], new[] { value });
            this.m_ObjectStorage.UpdateOrPut(new LiveEntry
            {
                Key   = message.SetPropertyObjectID,
                Value = obj,
                Owner = this.m_LocalNode.Self
            });

            var client = this.m_ClientLookup.Lookup(message.Sender.IPEndPoint);

            client.Send(this.m_MessageConstructor.ConstructSetPropertyConfirmationMessage(message.ID));
        }
示例#3
0
        public object GetProperty(string id, string property)
        {
            this.AssertBound();

            var messageConstructor       = this.GetService <IMessageConstructor>();
            var objectWithTypeSerializer = this.GetService <IObjectWithTypeSerializer>();
            var automaticRetry           = this.GetService <IAutomaticRetry>();

            var entry = this.GetHandlerAndObjectByID(id);
            var obj   = entry.Value;

            if (this.Architecture == Architecture.PeerToPeer && entry.Owner != this.Self)
            {
                // We need to request the value from the node that owns it.
                var getMessage = messageConstructor.ConstructGetPropertyMessage(ID.NewHash(id), property);

                var message = automaticRetry.SendWithRetry(
                    entry.ClientHandler,
                    getMessage,
                    x => x.Type == MessageType.GetPropertyResult && x.GetPropertyMessageID == getMessage.ID,
                    this.Timeout,
                    this.Retries);

                return(objectWithTypeSerializer.Deserialize(message.GetPropertyResult));
            }

            if (this.Architecture == Architecture.ServerClient)
            {
                if (!this.IsServer && this.Caching != Caching.PushOnChange)
                {
                    // We are the client, but we need to request the value
                    // from the server.
                    var getMessage = messageConstructor.ConstructGetPropertyMessage(ID.NewHash(id), property);

                    var message = automaticRetry.SendWithRetry(
                        entry.ClientHandler,
                        getMessage,
                        x => x.Type == MessageType.GetPropertyResult && x.GetPropertyMessageID == getMessage.ID,
                        this.Timeout,
                        this.Retries);

                    return(objectWithTypeSerializer.Deserialize(message.GetPropertyResult));
                }
            }

            var mi = obj.GetType().GetMethod("get_" + property + "__Distributed0", BindingFlagsCombined.All);

            if (mi == null)
            {
                throw new MissingMethodException(obj.GetType().FullName, "get_" + property + "__Distributed0");
            }

            return(DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, new Type[0], new object[] { }));
        }
示例#4
0
        public void Handle(Message message)
        {
            if (message.InvokeTypeArguments == null)
            {
                message.InvokeTypeArguments = new string[0];
            }

            if (message.InvokeArguments == null)
            {
                message.InvokeArguments = new ObjectWithType[0];
            }

            var entry = this.m_ObjectStorage.Find(message.InvokeObjectID).FirstOrDefault();

            if (entry == null)
            {
                throw new InvalidOperationException("Invoke message received but we don't own the object!");
            }

            var obj = entry.Value;

            var mi = obj.GetType().GetMethod(message.InvokeMethod, BindingFlagsCombined.All);

            if (mi == null)
            {
                throw new MissingMethodException(obj.GetType().FullName, message.InvokeMethod);
            }

            var targs = message.InvokeTypeArguments.Select(Type.GetType).ToArray();
            var args  = message.InvokeArguments.Select(x => this.m_ObjectWithTypeSerializer.Deserialize(x)).ToArray();

            var allowed = false;

            if (this.m_LocalNode.Architecture == Architecture.PeerToPeer)
            {
                // In peer-to-peer, all methods are callable.
                allowed = true;
            }
            else if (this.m_LocalNode.Architecture == Architecture.ServerClient)
            {
                if (message.Sender == this.m_LocalNode.Self)
                {
                    // This message is coming from the server.
                    allowed = true;
                }
                else
                {
                    var originalName   = mi.Name.Substring(0, mi.Name.Length - "__Distributed0".Length);
                    var originalMethod = obj.GetType().GetMethod(originalName, BindingFlagsCombined.All);

                    // The client is calling this method, ensure they are allowed to call it.
                    allowed = originalMethod.GetCustomAttributes(typeof(ClientCallableAttribute), false).Any();
                }
            }

            if (!allowed)
            {
                // If the sender is not permitted to call this method, we just return (we
                // don't even bother giving them a response since they're either using an
                // out-of-date client or attempting to bypass security).
                throw new InvalidOperationException("Received a call to invoke " + message.InvokeMethod + " on " + obj.GetType());
            }

            var result = DpmEntrypoint.InvokeDynamic(
                obj.GetType(),
                mi,
                obj,
                targs,
                args);

            var client = this.m_ClientLookup.Lookup(message.Sender.IPEndPoint);

            client.Send(this.m_MessageConstructor.ConstructInvokeResultMessage(message.ID, result));
        }
示例#5
0
        public DList(IEnumerable <T> collection)
        {
            DpmEntrypoint.Construct(this);

            this.m_List = new List <T>(collection);
        }
示例#6
0
        public DList(int capacity)
        {
            DpmEntrypoint.Construct(this);

            this.m_List = new List <T>(capacity);
        }
示例#7
0
 public DList()
 {
     DpmEntrypoint.Construct(this);
 }
示例#8
0
        public void SetProperty(string id, string property, object value)
        {
            this.AssertBound();

            var objectStorage      = this.GetService <IObjectStorage>();
            var clientLookup       = this.GetService <IClientLookup>();
            var messageConstructor = this.GetService <IMessageConstructor>();
            var automaticRetry     = this.GetService <IAutomaticRetry>();

            var entry = this.GetHandlerAndObjectByID(id);
            var obj   = entry.Value;

            var mi = obj.GetType().GetMethod("set_" + property + "__Distributed0", BindingFlagsCombined.All);

            if (mi == null)
            {
                throw new MissingMethodException(obj.GetType().FullName, "set_" + property + "__Distributed0");
            }

            if (this.Architecture == Architecture.PeerToPeer)
            {
                if (entry.Owner == this.Self)
                {
                    DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, new Type[0], new[] { value });
                    objectStorage.UpdateOrPut(new LiveEntry {
                        Key = ID.NewHash(id), Value = obj, Owner = this.Self
                    });
                    return;
                }

                var clientHandler      = clientLookup.Lookup(entry.Owner.IPEndPoint);
                var setPropertyMessage = messageConstructor.ConstructSetPropertyMessage(ID.NewHash(id), property, value);

                automaticRetry.SendWithRetry(
                    clientHandler,
                    setPropertyMessage,
                    x =>
                    x.Type == MessageType.SetPropertyConfirmation && x.SetPropertyMessageID == setPropertyMessage.ID,
                    this.Timeout,
                    this.Retries);

                return;
            }

            if (this.Architecture == Architecture.ServerClient)
            {
                // If we are a client, we can't set properties.
                if (!this.IsServer)
                {
                    throw new MemberAccessException("Only servers may set the '" + property + "' property.");
                }

                DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, new Type[0], new[] { value });
                objectStorage.UpdateOrPut(new LiveEntry {
                    Key = ID.NewHash(id), Value = obj, Owner = this.Self
                });

                if (this.Caching == Caching.PushOnChange)
                {
                    // We need to push the new value out to clients.
                    foreach (var client in clientLookup.GetAll().Where(x => !object.Equals(x.Key, this.Self.IPEndPoint)))
                    {
                        client.Value.Send(
                            messageConstructor.ConstructSetPropertyMessage(ID.NewHash(id), property, value));
                    }
                }

                return;
            }

            throw new NotSupportedException();
        }
示例#9
0
        public object Invoke(string id, string method, Type[] targs, object[] args)
        {
            this.AssertBound();

            var messageConstructor       = this.GetService <IMessageConstructor>();
            var objectWithTypeSerializer = this.GetService <IObjectWithTypeSerializer>();
            var automaticRetry           = this.GetService <IAutomaticRetry>();

            var entry = this.GetHandlerAndObjectByID(id);
            var obj   = entry.Value;

            if (this.Architecture == Architecture.PeerToPeer)
            {
                // In peer-to-peer modes, methods are always invoked locally.
                var mi = obj.GetType().GetMethod(method, BindingFlagsCombined.All);
                if (mi == null)
                {
                    throw new MissingMethodException(obj.GetType().FullName, method);
                }

                return(DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, targs, args));
            }

            if (this.Architecture == Architecture.ServerClient)
            {
                if (this.IsServer)
                {
                    // The server is always permitted to call methods.
                    var mi = obj.GetType().GetMethod(method, BindingFlagsCombined.All);
                    if (mi == null)
                    {
                        throw new MissingMethodException(obj.GetType().FullName, method);
                    }

                    return(DpmEntrypoint.InvokeDynamic(obj.GetType(), mi, obj, targs, args));
                }
                else
                {
                    // We must see if the client is permitted to call the specified method.
                    var mi = obj.GetType()
                             .GetMethod(method.Substring(0, method.IndexOf("__Distributed0", System.StringComparison.Ordinal)), BindingFlagsCombined.All);
                    if (mi == null)
                    {
                        throw new MissingMethodException(obj.GetType().FullName, method);
                    }

                    if (mi.GetCustomAttributes(typeof(ClientIgnorableAttribute), false).Count() != 0)
                    {
                        return(null);
                    }

                    if (!mi.GetCustomAttributes(typeof(ClientCallableAttribute), false).Any())
                    {
                        throw new MemberAccessException(
                                  "The method '" + method + "' is not accessible to client machines.");
                    }

                    // If we get to here, then we're permitted to call the method, but we still need
                    // to remote it to the server.
                    var invokeMessage = messageConstructor.ConstructInvokeMessage(ID.NewHash(id), method, targs, args);

                    var message = automaticRetry.SendWithRetry(
                        entry.ClientHandler,
                        invokeMessage,
                        x => x.Type == MessageType.InvokeResult && x.InvokeMessageID == invokeMessage.ID,
                        this.Timeout,
                        this.Retries);

                    return(objectWithTypeSerializer.Deserialize(message.InvokeResult));
                }
            }

            throw new NotSupportedException();
        }