예제 #1
0
 public override async Task IfEffect(StateMachineEvent evt, Command parameter)
 {
     var supportsMessage = new Supports(InformationMessageHeader, new HashSet<string>(Features), null);
     await Sender.SendMessage(supportsMessage.ToMessage());
     var sidMessage = new Sid(new InformationMessageHeader(), User.Sid);
     await Sender.SendMessage(sidMessage.ToMessage());
 }
예제 #2
0
 protected async Task EchoedDirectCommand(Command command)
 {
     var echoMessageType = (EchoMessageHeader)command.Header;
     var sender = ActorProxy.Create<ISender>(new ActorId(echoMessageType.TargetSid));
     await sender.SendMessage(command.OriginalMessage);
     await Sender.SendMessage(command.OriginalMessage);
 }
예제 #3
0
 public override async Task IfEffect(StateMachineEvent evt, Command parameter)
 {
     var command = (Information)parameter;
     await _user.UpdateInformation(command);
     var hubInformation = CreateHubInformation();
     await Sender.SendMessage(hubInformation.ToMessage());
 }
예제 #4
0
        public override async Task<bool> Guard(StateMachineEvent evt, Command parameter)
        {
            var command = (Information)parameter;
            if (!command.Pid.IsDefined)
            {
                CreateRequiredFieldIsMissing("PD");
                return false;
            }

            if (!command.Cid.IsDefined)
            {
                CreateRequiredFieldIsMissing("ID");
                return false;
            }

            var cid = AdcBase32Encoder.Decode(command.Cid.Value);
            var pid = AdcBase32Encoder.Decode(command.Pid.Value);
            var hash = new TigerHash().ComputeHash(pid);
            if (!hash.SequenceEqual(cid))
            {
                CreateInvalidPid();
                return false;
            }

            if (!command.IpAddressV4.IsDefined && !command.IpAddressV6.IsDefined)
            {
                CreateRequiredFieldIsMissing("I4");
                return false;
            }

            if (command.IpAddressV4.IsDefined && command.IpAddressV4.Value != _user.ClientIPv4.ToString())
            {
                CreateInvalidIPv4(_user.ClientIPv4.ToString());
                return false;
            }

            if (command.IpAddressV6.IsDefined && command.IpAddressV6.Value != _user.ClientIPv6.ToString())
            {
                CreateInvalidIPv6(_user.ClientIPv6.ToString());
                return false;
            }

            if (!command.Nickname.IsDefined || string.IsNullOrWhiteSpace(command.Nickname.Value))
            {
                CreateInvalidNick();
                return false;
            }

            var catalog = ServiceProxy.Create<ICatalog>(new Uri("fabric:/FabricAdcHub.ServiceFabric/Catalog"));
            if (!await catalog.ReserveNick(_user.Sid, command.Nickname.Value))
            {
                CreateNonUniqueNick();
                return false;
            }

            return true;
        }
        public override async Task Effect(StateMachineEvent evt, Command parameter)
        {
            if (parameter != null)
            {
                var status = new Status(new InformationMessageHeader(), Status.ErrorSeverity.Fatal, Status.ErrorCode.InvalidState, $"Command {parameter.FourCc()} is invalid or not available in PROTOCOL state.");
                status.OffendingCommandOrMissingFeature.Value = parameter.FourCc();
                await Sender.SendMessage(status.ToMessage());
            }

            await User.Close();
        }
예제 #6
0
        public override Task<bool> Guard(StateMachineEvent evt, Command parameter)
        {
            var command = (Supports)parameter;
            for (var index = 0; index != Features.Length; index++)
            {
                var feature = Features[index];
                if (!command.AddFeatures.Value.Contains(feature))
                {
                    CreateRequiredFeatureIsMissing(feature);
                    return Task.FromResult(false);
                }
            }

            return Task.FromResult(true);
        }
        public override async Task Effect(StateMachineEvent evt, Command parameter)
        {
            if (parameter != null)
            {
                var status = new Status(new InformationMessageHeader(), Status.ErrorSeverity.Fatal, Status.ErrorCode.InvalidState, $"Command {parameter.FourCc()} is invalid or not available in IDENTIFY state.");
                status.OffendingCommandOrMissingFeature.Value = parameter.FourCc();
                await Sender.SendMessage(status.ToMessage());
            }

            if (evt.InternalEvent != InternalEvent.DisconnectOccured)
            {
                var quit = new Quit(new InformationMessageHeader(), User.Sid);
                await Sender.SendMessage(quit.ToMessage());
            }

            await User.Close();
        }
예제 #8
0
        public static bool TryCreateFromMessage(string message, out Command command)
        {
            command = null;
            if (string.IsNullOrWhiteSpace(message))
            {
                return false;
            }

            var parts = SplitText(message);
            var messageTypeAndName = parts[0];
            if (messageTypeAndName.Length != 4)
            {
                return false;
            }

            var parameters = parts.Skip(1).ToList();

            var messageTypeSymbol = messageTypeAndName[0];
            if (!MessageHeaderCreators.ContainsKey(messageTypeSymbol))
            {
                return false;
            }

            var messageHeader = MessageHeaderCreators[messageTypeSymbol](parameters);
            var commandName = messageTypeAndName.Substring(1, 3);
            if (!CommandCreators.ContainsKey(commandName))
            {
                return false;
            }

            var commandType = CommandType.FromText(commandName);
            var positionalParameters = parameters
                .Skip(messageHeader.Type.NumberOfParameters)
                .Take(commandType.NumberOfParameters)
                .ToList();
            var namedParameters = parameters
                .Skip(messageHeader.Type.NumberOfParameters)
                .Skip(commandType.NumberOfParameters)
                .ToList();
            command = CommandCreators[commandName](messageHeader, positionalParameters, namedParameters, message);
            return true;
        }
예제 #9
0
        public override async Task Effect(StateMachineEvent evt, Command parameter)
        {
            if (evt.InternalEvent == InternalEvent.ConnectionTimedOut)
            {
                // do nothing
                return;
            }

            if (parameter.Type == CommandType.Information)
            {
                await User.UpdateInformation((Information)parameter);
            }
            else if (parameter.Type == CommandType.Supports)
            {
                await User.UpdateInformation((Supports)parameter);
            }

            if (parameter.Header is BroadcastMessageHeader)
            {
                await BroadcastCommand(parameter);
                return;
            }

            if (parameter.Header is DirectMessageHeader)
            {
                await DirectCommand(parameter);
                return;
            }

            if (parameter.Header is EchoMessageHeader)
            {
                await EchoedDirectCommand(parameter);
                return;
            }

            if (parameter.Header is FeatureBroadcastMessageHeader)
            {
                await FeatureBroadcastCommand(parameter);
            }
        }
예제 #10
0
 public override async Task ElseEffect(StateMachineEvent evt, Command parameter)
 {
     var quit = new Quit(new InformationMessageHeader(), _user.Sid);
     await Sender.SendMessage(quit.ToMessage());
     await _user.Close();
 }
예제 #11
0
 public async Task ProcessCommand(Command command)
 {
     await _stateMachine.Fire(new StateMachineEvent(InternalEvent.AdcMessageReceived, command.Type), command);
 }
예제 #12
0
 protected async Task FeatureBroadcastCommand(Command command)
 {
     var featureBroadcastMessageHeader = (FeatureBroadcastMessageHeader)command.Header;
     var catalog = ServiceProxy.Create<ICatalog>(new Uri("fabric:/FabricAdcHub.ServiceFabric/Catalog"), targetReplicaSelector: TargetReplicaSelector.RandomReplica);
     await catalog.FeatureBroadcastMessage(User.Sid, featureBroadcastMessageHeader.RequiredFeatures.ToList(), featureBroadcastMessageHeader.ExcludedFeatures.ToList(), command.ToMessage());
 }
예제 #13
0
 public override Task ElseEffect(StateMachineEvent evt, Command parameter)
 {
     return Sender.SendMessage(_errorCommand.ToMessage());
 }
예제 #14
0
 protected async Task BroadcastCommand(Command command)
 {
     var catalog = ServiceProxy.Create<ICatalog>(new Uri("fabric:/FabricAdcHub.ServiceFabric/Catalog"), targetReplicaSelector: TargetReplicaSelector.RandomReplica);
     await catalog.BroadcastMessage(User.Sid, command.OriginalMessage);
 }
 public override async Task Effect(StateMachineEvent evt, Command parameter)
 {
     await User.Close();
 }
예제 #16
0
        private async Task SendCommand(Command command)
        {
            var message = command.ToMessage();
            ServiceEventSource.Current.AdcMessageSent(message);

            var messageBytes = Encoding.UTF8.GetBytes(message + "\n");
            await _tcpClient.GetStream().WriteAsync(messageBytes, 0, messageBytes.Length);
        }
예제 #17
0
 public override Task<bool> Guard(StateMachineEvent evt, Command parameter)
 {
     var status = (Status)parameter;
     return Task.FromResult(status.Severity == Status.ErrorSeverity.Fatal);
 }
예제 #18
0
 public override Task IfEffect(StateMachineEvent evt, Command parameter)
 {
     return Task.CompletedTask;
 }