/// <summary>Processes the command message.</summary> /// <param name="cmdMsg">The command MSG.</param> public void ProcessCommandMessage(ObjectCommandEnvelope cmdMsg) { if (OnCommand != null) { OnCommand.Invoke(cmdMsg); } }
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); }
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); }
/// <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); }
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); }
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); }
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))); }
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++; }
/// <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); }
/// <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; }
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); }); }
/// <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; }
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 }); } }
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); }