Example #1
0
 /// <summary>Processes the command message.</summary>
 /// <param name="cmdMsg">The command MSG.</param>
 public void ProcessCommandMessage(ObjectCommandEnvelope cmdMsg)
 {
     if (OnCommand != null)
     {
         OnCommand.Invoke(cmdMsg);
     }
 }
Example #2
0
        private IActorRef CreateDefaultObjectActor(TestProbe areaRegionProbe, AVector3 pos)
        {
            //setup
            var localShardRegionResolver = new Mock <IShardRegionResolver>();

            localShardRegionResolver.Setup(m => m.GetShardRegion(ShardRegions.AREAREGION)).Returns(areaRegionProbe);
            var testeeRef = Sys.ActorOf(Props.Create(() => new ObjectActor(localShardRegionResolver.Object)), DEFAULTOBJECTID.ToString(CultureInfo.InvariantCulture));

            Watch(testeeRef);
            var cmdCreate = new ObjectCreateCommand(
                frameTick: 0,
                objectId: DEFAULTOBJECTID,
                parentObjectId: 0,
                ownerId: 0,
                typeId: 0,
                targetPosition: pos,
                targetOrientation: new AQuaternion
            {
                X = 40.0f,
                Y = 50.0f,
                Z = 60.0f,
                W = 70.0f
            });
            var cmdEnvCreate = new ObjectCommandEnvelope(0, cmdCreate, DEFAULTOBJECTID);

            //execute
            testeeRef.Tell(cmdEnvCreate);

            //verify
            areaRegionProbe.ExpectMsg <ObjectEnterAreaCommand>();
            areaRegionProbe.ExpectMsg <AreaCommandEnvelope>();
            return(testeeRef);
        }
        private T TellArea <T>(ObjectCommandEnvelope cmdMsg, Func <BaseCommand, T> createFunc)
            where T : BaseCommand, IAreaCommand
        {
            T cmd = createFunc(cmdMsg.Command);

            this.shardRegionArea.Tell(new AreaCommandEnvelope(cmd.AreaId, new ObjectCommandEnvelope(0, cmd, 0)));
            return(cmd);
        }
Example #4
0
        private MessageStatistic RunStatistics(CliClient client, MessageControlFlags flags, string domain, int messageCount, Func <ulong, BaseCommand> createCommand)
        {
            ConcurrentDictionary <ulong, MessageEntry> messages = new ConcurrentDictionary <ulong, MessageEntry>();

            client.OnCommand = (cmd) => ProcessCommandMessage(client, domain, messages, cmd);
            DateTime startTimeStamp = DateTime.Now;
            ulong    objectId       = (ulong)(client.ClientId * messageCount);

            for (int i = 0; i < messageCount; i++)
            {
                objectId++;
                BaseCommand           command    = createCommand(objectId);
                ObjectCommandEnvelope commandEnv = new ObjectCommandEnvelope(client.ClientId, command, objectId);
                messages.TryAdd(objectId, new MessageEntry {
                    RequestTimeStamp = DateTime.Now, ResponseTimeStamp = DateTime.MinValue, CommandEnvelope = commandEnv
                });
                client.ReliableMessaging.SendCommandEnvelope(commandEnv, flags);
                TimeSpan waitTime = client.ReliableMessaging.SynchronizeMessages();
                if (waitTime > TimeSpan.Zero)
                {
                    Thread.Sleep((int)waitTime.TotalMilliseconds);
                }
            }
            for (; ;)
            {
                if (DateTime.Now - client.LastMessageReceived > TimeSpan.FromSeconds(5))
                {
                    break;
                }
                Thread.Sleep(200);
                TimeSpan waitTime = client.ReliableMessaging.SynchronizeMessages();
                if (waitTime > TimeSpan.Zero)
                {
                    Thread.Sleep((int)waitTime.TotalMilliseconds);
                }
            }
            TimeSpan sumLatency   = TimeSpan.Zero;
            int      countSuccess = 0;

            foreach (var value in messages.Values)
            {
                if (value.ResponseTimeStamp == DateTime.MinValue)
                {
                    break;
                }
                countSuccess++;
                sumLatency += value.ResponseTimeStamp - value.RequestTimeStamp;
            }
            MessageStatistic messageStatistic = new MessageStatistic();

            messageStatistic.Duration         = client.LastMessageReceived - startTimeStamp;
            messageStatistic.MessagesTotal    = messageCount;
            messageStatistic.MessagesAnswered = countSuccess;
            return(messageStatistic);
        }
Example #5
0
        /// <summary>Sends a command envelope.</summary>
        /// <param name="commandEnvelope">The command envelope.</param>
        /// <param name="qualityOfService">The quality of service.</param>
        /// <exception cref="ArgumentNullException">commandEnvelope is null.</exception>
        public void SendCommandEnvelope(ObjectCommandEnvelope commandEnvelope, MessageControlFlags qualityOfService = MessageControlFlags.QOS0)
        {
            if (commandEnvelope == null)
            {
                throw new ArgumentNullException(nameof(commandEnvelope));
            }

            var message = new UdpMessage(this.sequenceId, MessageControlFlags.COMMAND | qualityOfService, commandEnvelope.Serialize());

            this.sequenceId++;
            this.pendingMessages.Enqueue(message);
        }
Example #6
0
        public void ActorMustIgnoreAnyNonOwnerCommand()
        {
            //setup
            const uint LOCKOWNER       = 9999;
            const uint NONLOCKOWNER    = 8888;
            var        areaRegionProbe = CreateTestProbe();
            IActorRef  testeeRef       = CreateDefaultObjectActor(areaRegionProbe);
            var        cmdLock         = new ObjectLockCommand(
                objectId: DEFAULTOBJECTID,
                lockOwnerId: LOCKOWNER,
                timeout: TimeSpan.FromMinutes(2)
                );
            var cmdEnvLock = new ObjectCommandEnvelope(LOCKOWNER, cmdLock, DEFAULTOBJECTID);

            var cmdUpdatePosition = new ObjectUpdatePositionCommand(
                DEFAULTOBJECTID,
                targetPosition: new AVector3
            {
                X = 10.0f,
                Y = 20.0f,
                Z = 30.0f,
            },
                targetOrientation: new AQuaternion
            {
                X = 40.0f,
                Y = 50.0f,
                Z = 60.0f,
                W = 70.0f,
            },
                startFrameTick: 0,
                stopFrameTick: 0
                );
            var cmdEnvUpdatePosition = new ObjectCommandEnvelope(NONLOCKOWNER, cmdUpdatePosition, DEFAULTOBJECTID);

            //execute
            testeeRef.Tell(cmdEnvLock);

            //verify - update position in new are
            areaRegionProbe.ExpectMsg <AreaCommandEnvelope>(m =>
            {
                Assert.Equal(CommandType.ObjectLock, m.ObjectCommandEnvelope.Command.Type);
                Assert.Equal(Locator.GetAreaIdFromWorldPosition(DEFAULTVECTOR), m.ToAreaId);
            });

            //execute
            testeeRef.Tell(cmdEnvUpdatePosition);

            areaRegionProbe.ExpectNoMsg();
        }
        private T TellObject <T>(ObjectCommandEnvelope cmdMsg, Func <BaseCommand, T> createFunc)
            where T : BaseCommand, IObjectCommand
        {
            T      cmd             = createFunc(cmdMsg.Command);
            var    commandEnvelope = new ObjectCommandEnvelope(cmdMsg.SenderId, cmd, cmdMsg.ToObjectId);
            object message         = commandEnvelope;

            if ((cmd.Flags & CommandFlags.QuorumRequest) != 0)
            {
                message = new QuorumRequestEnvelope(commandEnvelope);
            }

            this.shardRegionObject.Tell(message);
            return(cmd);
        }
Example #8
0
        private void PublishCommand(ObjectCommandEnvelope command)
        {
            if (this.state.Subscriptions.Values.Count == 0)
            {
                this.log.Warning($"No subscribers!");
            }

            foreach (Subscription sub in this.state.Subscriptions.Values)
            {
                if (sub.MessagePriority <= command.Command.Priority)
                {
                    this.log.Debug($"{this.Self.Path} => forwarding to {sub.SubscriberActorRef.Path}");
                    sub.SubscriberActorRef.Tell(new ObjectCommandResponseEnvelope(command));
                }
            }
        }
        private T TellEvent <T>(ObjectCommandEnvelope cmdMsg, Func <BaseCommand, T> createFunc, Func <T, IEnumerable <ulong> > extractAreas)
            where T : BaseCommand, ICanLocate
        {
            T   cmd   = createFunc(cmdMsg.Command);
            var areas = extractAreas(cmd);

            if (!areas.Any())
            {
                this.log.Warning($"[{this.Self.Path.Name}] no areas for event [{cmd.Type}]");
            }

            foreach (ulong areaId in areas)
            {
                this.shardRegionArea.Tell(new AreaCommandEnvelope(areaId, new ObjectCommandEnvelope(cmdMsg.SenderId, cmd, 0)));
            }

            return(cmd);
        }
Example #10
0
        private void ForwardToArea(ObjectCommandEnvelope objCmd)
        {
            if (!this.isInitialized)
            {
                this.log.Error($"[Object:{this.state.ObjectId}] Cannot forward command type '{objCmd.Command.Type}'. Actor is not initialized!");
                return;
            }

            ulong oldAreaId = Locator.GetAreaIdFromWorldPosition(this.state.LastWorldPosition);
            ulong newAreaId = Locator.GetAreaIdFromWorldPosition(this.state.WorldPosition);

            if (oldAreaId != newAreaId)
            {
                this.shardRegionArea.Tell(new AreaCommandEnvelope(oldAreaId, new ObjectCommandEnvelope(objCmd.SenderId, objCmd.Command, objCmd.ToObjectId)));
                this.NotifyEnterArea(objCmd.SenderId, newAreaId);
                this.NotifyLeaveArea(oldAreaId);
            }

            this.shardRegionArea.Tell(new AreaCommandEnvelope(newAreaId, new ObjectCommandEnvelope(objCmd.SenderId, objCmd.Command, objCmd.ToObjectId)));
        }
Example #11
0
        private void ProcessUdpMessage(UdpMessage message)
        {
            MessageEntry removedEntry;

            // QOS1 - at least once
            if ((message.ControlFlags & MessageControlFlags.ACK) == MessageControlFlags.ACK && this.unAckedMessages.ContainsKey(message.SequenceId))
            {
                this.unAckedMessages.TryRemove(message.SequenceId, out removedEntry);

                // QOS2 - at most once
                if ((message.ControlFlags & MessageControlFlags.QOS2) == MessageControlFlags.QOS2)
                {
                    this.pendingAckMessages.Enqueue(message);
                }
            }

            // QOS2 - at most once
            if (message.ControlFlags == MessageControlFlags.ACK2 && this.unAckedMessages.ContainsKey(message.SequenceId))
            {
                this.unAckedMessages.TryRemove(message.SequenceId, out removedEntry);
            }

            if ((message.ControlFlags & MessageControlFlags.COMMAND) == MessageControlFlags.COMMAND)
            {
                var cmdEnvelope = new ObjectCommandEnvelope(message);
                this.OnProcessCommandMessage(cmdEnvelope);

                // QOS 1 - at least once
                if ((message.ControlFlags & MessageControlFlags.QOS1) == MessageControlFlags.QOS1)
                {
                    this.pendingAckMessages.Enqueue(message);
                }
            }

            this.MessageReceivedCount++;
        }
Example #12
0
        /// <summary>Sends a command.</summary>
        /// <param name="senderId">The sender identifier.</param>
        /// <param name="command">The command.</param>
        /// <param name="toObjectId">To object identifier.</param>
        /// <param name="qualityOfService">The quality of service.</param>
        public void SendCommand(uint senderId, BaseCommand command, ulong toObjectId, MessageControlFlags qualityOfService = MessageControlFlags.QOS0)
        {
            var commandEnvelope = new ObjectCommandEnvelope(senderId, command, toObjectId);

            this.SendCommandEnvelope(commandEnvelope, qualityOfService);
        }
Example #13
0
 /// <summary>Initializes a new instance of the <see cref="ObjectCommandResponseEnvelope" /> class.</summary>
 /// <param name="message">The message.</param>
 public ObjectCommandResponseEnvelope(ObjectCommandEnvelope message)
 {
     this.Message = message;
 }
Example #14
0
        public void ActorMustUpdateLocationMustInformOldAndNewArea()
        {
            //setup
            var       areaRegionProbe = CreateTestProbe();
            IActorRef testeeRef       = CreateDefaultObjectActor(areaRegionProbe);
            float     newPosX         = 3000.0f;
            float     newPosY         = 4000.0f;
            float     newPosZ         = 5000.0f;

            var cmdUpdatePosition = new ObjectUpdatePositionCommand(
                DEFAULTOBJECTID,
                targetPosition: new AVector3
            {
                X = newPosX,
                Y = newPosY,
                Z = newPosZ
            },
                targetOrientation: new AQuaternion
            {
                X = 40.0f,
                Y = 50.0f,
                Z = 60.0f,
                W = 70.0f
            },
                startFrameTick: 0,
                stopFrameTick: 0
                );
            var cmdEnvUpdatePosition = new ObjectCommandEnvelope(0, cmdUpdatePosition, DEFAULTOBJECTID);
            var expectedOldAreaId    = Locator.GetAreaIdFromWorldPosition(DEFAULTVECTOR);
            var expectedNewAreaId    = Locator.GetAreaIdFromWorldPosition(cmdUpdatePosition.TargetPosition);

            //execute
            testeeRef.Tell(cmdEnvUpdatePosition);

            //verify - update position in old area
            areaRegionProbe.ExpectMsg <AreaCommandEnvelope>(m =>
            {
                Assert.Equal(CommandType.ObjectUpdatePosition, m.ObjectCommandEnvelope.Command.Type);
                Assert.Equal(expectedOldAreaId, m.ToAreaId);
            });

            //verify - notify enter new area
            areaRegionProbe.ExpectMsg <ObjectEnterAreaCommand>(m =>
            {
                Assert.Equal(expectedNewAreaId, m.AreaId);
                Assert.Equal(cmdEnvUpdatePosition.ToObjectId, m.ObjectId);
            });

            //verify - notify leave old area
            areaRegionProbe.ExpectMsg <ObjectLeaveAreaCommand>(m =>
            {
                Assert.Equal(expectedOldAreaId, m.AreaId);
                Assert.Equal(cmdEnvUpdatePosition.ToObjectId, m.ObjectId);
            });

            //verify - update position in new are
            areaRegionProbe.ExpectMsg <AreaCommandEnvelope>(m =>
            {
                Assert.Equal(CommandType.ObjectUpdatePosition, m.ObjectCommandEnvelope.Command.Type);
                Assert.Equal(expectedNewAreaId, m.ToAreaId);
            });
        }
Example #15
0
 /// <summary>Initializes a new instance of the <see cref="ObjectCommandRequestEnvelope" /> class.</summary>
 /// <param name="message">The message.</param>
 public ObjectCommandRequestEnvelope(ObjectCommandEnvelope message)
 {
     this.Message = message;
 }
Example #16
0
        private void ProcessCommandMessage(CliClient client, string domain, ConcurrentDictionary <ulong, MessageEntry> messages, ObjectCommandEnvelope commandEnvelope)
        {
            BaseCommand responseCommand = null;

            switch ((CommandType)commandEnvelope.Command.Type)
            {
            case CommandType.ObjectCreate:
                responseCommand = new ObjectCreateCommand(commandEnvelope.Command);
                break;

            case CommandType.ObjectUpdatePosition:
                responseCommand = new ObjectUpdatePositionCommand(commandEnvelope.Command);
                break;

            case CommandType.ObjectDestroy:
                responseCommand = new ObjectDestroyCommand(commandEnvelope.Command);
                break;
            }
            if (!messages.ContainsKey(commandEnvelope.ToObjectId))
            {
                Log.WriteLine($"[{client.ClientId} ERROR: {domain} mMessage {commandEnvelope.ToObjectId} is missing");
                return;
            }
            messages[commandEnvelope.ToObjectId].ResponseTimeStamp = DateTime.Now;
            messages[commandEnvelope.ToObjectId].ResponseCount++;
            byte[] responseData = commandEnvelope.Serialize();
            byte[] requestData  = messages[commandEnvelope.ToObjectId].CommandEnvelope.Serialize();
            if (!ComparyBinary(responseData, requestData))
            {
                Log.WriteLine($"{client.ClientId} ERROR: {domain} message {commandEnvelope.ToObjectId} invalid response");
            }
        }
        private void ProcessRequestFromClient(ObjectCommandEnvelope cmdMsg)
        {
            try
            {
                BaseCommand parsedCommand = null;
                switch (cmdMsg.Command.Type)
                {
                case CommandType.SubscribeArea:
                    parsedCommand = this.TellArea(cmdMsg, _ => new SubscribeAreaCommand(_));
                    break;

                case CommandType.UnsubscribeArea:
                    parsedCommand = this.TellArea(cmdMsg, _ => new UnsubscribeAreaCommand(_));
                    break;

                case CommandType.ObjectUpdatePosition:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectUpdatePositionCommand(_));
                    break;

                case CommandType.ObjectCreate:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectCreateCommand(_));
                    break;

                case CommandType.ObjectDestroy:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectDestroyCommand(_));
                    break;

                case CommandType.ObjectLock:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectLockCommand(_));
                    break;

                case CommandType.ObjectUnlock:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectUnlockCommand(_));
                    break;

                case CommandType.ObjectValueUpdate:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectValueUpdateCommand(_));
                    break;

                case CommandType.ObjectValueRemove:
                    parsedCommand = this.TellObject(cmdMsg, _ => new ObjectValueRemoveCommand(_));
                    break;

                case CommandType.EventPoint:
                    parsedCommand = this.TellEvent(cmdMsg, _ => new EventPointCommand(_), _ => new[] { Locator.GetAreaIdFromWorldPosition(_.TargetPosition) });
                    break;

                case CommandType.EventLine:
                    parsedCommand = this.TellEvent(cmdMsg, _ => new EventLineCommand(_), _ => Locator.GetAreaIdsWithinWorldBoundaries(_.StartPosition, _.EndPosition));
                    break;
                }

                string commandInfo = parsedCommand != null?parsedCommand.ToString() : string.Empty;

                this.log.Debug($"[Client:{this.state.ClientId} => Server] type: {cmdMsg.Command.Type} ({commandInfo})");
            }
#pragma warning disable CA1031 // Keine allgemeinen Ausnahmetypen abfangen
            catch (Exception e)
#pragma warning restore CA1031 // Keine allgemeinen Ausnahmetypen abfangen
            {
                this.Sender.Tell(new Failure()
                {
                    Exception = e
                });
            }
        }
Example #18
0
        public void ActorMustNotifyAreaRegionOnCreationAndDestruction()
        {
            //setup
            var areRegionProbe           = CreateTestProbe();
            var localShardRegionResolver = new Mock <IShardRegionResolver>();

            localShardRegionResolver.Setup(m => m.GetShardRegion(ShardRegions.AREAREGION)).Returns(areRegionProbe);
            var testeeRef = Sys.ActorOf(Props.Create(() => new ObjectActor(localShardRegionResolver.Object)), DEFAULTOBJECTID.ToString(CultureInfo.InvariantCulture));

            Watch(testeeRef);

            var cmdCreate = new ObjectCreateCommand(
                frameTick: 0,
                objectId: DEFAULTOBJECTID,
                parentObjectId: 0,
                ownerId: 0,
                typeId: 0,
                targetPosition: new AVector3 {
                X = 10.0f,
                Y = 20.0f,
                Z = 30.0f,
            },
                targetOrientation: new AQuaternion {
                X = 40.0f,
                Y = 50.0f,
                Z = 60.0f,
                W = 70.0f,
            });
            var cmdEnvCreate = new ObjectCommandEnvelope(0, cmdCreate, DEFAULTOBJECTID);

            var cmdDestroy = new ObjectDestroyCommand(
                frameTick: 0,
                objectId: DEFAULTOBJECTID,
                targetPosition: new AVector3
            {
                X = 10.0f,
                Y = 20.0f,
                Z = 30.0f
            });
            var cmdEnvDestroy = new ObjectCommandEnvelope(0, cmdDestroy, DEFAULTOBJECTID);

            //execute
            testeeRef.Tell(cmdEnvCreate);

            //verify - object enters area
            areRegionProbe.ExpectMsg <ObjectEnterAreaCommand>(m => {
                Assert.Equal(DEFAULTOBJECTID, m.ObjectId);
                Assert.Equal(Locator.GetAreaIdFromWorldPosition(cmdCreate.TargetPosition), m.AreaId);
            });

            //create reaches area subscribers
            areRegionProbe.ExpectMsg <AreaCommandEnvelope>(m =>
            {
                Assert.Equal(Locator.GetAreaIdFromWorldPosition(cmdCreate.TargetPosition), m.ToAreaId);
                Assert.Equal(CommandType.ObjectCreate, m.ObjectCommandEnvelope.Command.Type);
            });

            //execute
            testeeRef.Tell(cmdEnvDestroy);

            //verify - object leaves area
            areRegionProbe.ExpectMsg <ObjectLeaveAreaCommand>(m => {
                Assert.Equal(DEFAULTOBJECTID, m.ObjectId);
                Assert.Equal(Locator.GetAreaIdFromWorldPosition(cmdDestroy.TargetPosition), m.AreaId);
            });

            //verify - destroy reaches area subscribers
            areRegionProbe.ExpectMsg <AreaCommandEnvelope>(m =>
            {
                Assert.Equal(Locator.GetAreaIdFromWorldPosition(cmdCreate.TargetPosition), m.ToAreaId);
                Assert.Equal(CommandType.ObjectDestroy, m.ObjectCommandEnvelope.Command.Type);
            });
            ExpectTerminated(testeeRef);
        }