Exemple #1
0
        private void ProcessClientFrame(IActorRef socketActorRef, Received received, UdpTransferFrame udpTransferFrame)
        {
            try
            {
                IActorRef clientTwinActor;
                if (udpTransferFrame.Type == FrameType.ClientHello)
                {
                    var cmdClientHello = new ClientHelloMessage(udpTransferFrame.MessageBuffer);
                    clientTwinActor = this.CreateClientTwinActor(socketActorRef, cmdClientHello.ClientId, received.Sender);
                }
                else
                {
                    clientTwinActor = this.GetClientTwinActor(received.Sender);
                }

                if (clientTwinActor == null)
                {
                    this.log.Warning("Invalid client {0}", received.Sender);
                    return;
                }

                clientTwinActor.Tell(udpTransferFrame, this.Self);
            }
#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
                });
            }
        }
Exemple #2
0
        /// <summary>Synchronizes all pending messages between local and remote.</summary>
        /// <returns>
        /// Suggested wait time. For example when send rate is exceeded.
        /// </returns>
        public TimeSpan SynchronizeMessages()
        {
            while (this.IsMessagePending())
            {
                if (this.IsSendRateExceeded())
                {
                    return(this.GetMessageWaitTime());
                }

                using (MemoryStream memstrm = new MemoryStream())
                {
                    this.AppendAckMessages(memstrm);
                    this.AppendUnAckedMessages(memstrm);
                    this.AppendPendingMessages(memstrm);

                    if (memstrm.Length > 0)
                    {
                        UdpTransferFrame frame = new UdpTransferFrame(FrameType.Message, memstrm.ToArray());
                        this.OnSendFrame(frame);
                        this.lastSentTimeStamp = DateTime.Now;
                    }
                }
            }

            return(TimeSpan.Zero);
        }
        private void ProcessUdpTransferFrame(UdpTransferFrame frame)
        {
            this.UpdateKeepAlive();
            switch (frame.Type)
            {
            case FrameType.ClientPing:
                this.log.Debug($"[Client:{this.state.ClientId} => Server] PING");
                var cmdClientPing = new ClientPingMessage(frame.MessageBuffer);
                var now           = TimeSpan.FromTicks(DateTime.UtcNow.Ticks);
                var msgServerPong = new ServerPongMessage()
                {
                    ClientRequestTimestamp = cmdClientPing.ClientTimestamp, ClientResponseTimestamp = now, ServerTimestamp = now
                };
                this.SendFrameToClient(FrameType.ServerPong, msgServerPong.Serialize());
                break;

            case FrameType.ClientPong:
                this.log.Debug($"[Client:{this.state.ClientId} => Server] PONG");
                var msgClientPong = new ClientPongMessage(frame.MessageBuffer);
                this.CalculateClientLatency(msgClientPong);
                break;

            case FrameType.Message:
                this.reliableClientMessaging.ProcessMessageFrame(frame);
                break;
            }
        }
        /// <summary>Initializes the communication.</summary>
        /// <param name="clientPort">The client port.</param>
        private void InitializeCommunication(uint clientPort)
        {
            var msgClientHello = new ClientHelloMessage()
            {
                ClientId = ClientId, ClientPort = clientPort, Message = $"Hello from {ClientId}", Version = Shared.Constants.Version.PROTOCOL
            };
            UdpTransferFrame frame = new UdpTransferFrame(FrameType.ClientHello, msgClientHello.Serialize());

            ReliableMessaging.OnSendFrame(frame);
        }
 /// <summary>Runs this instance.</summary>
 private void Run()
 {
     byte[] receiveBuffer;
     do
     {
         IPEndPoint bindToServerEndpoint = new IPEndPoint(serverEndPoint.Address, serverEndPoint.Port);
         receiveBuffer = client.Receive(ref bindToServerEndpoint);
         var udpTransferFrame = new UdpTransferFrame(receiveBuffer);
         ProcessUdpTransferFrame(udpTransferFrame);
     } while (receiveBuffer != null && receiveBuffer.Length > 0);
 }
Exemple #6
0
        private IActorRef CreateAuthenticatedActor(TestProbe authenticationProbe, TestProbe clientSocketProbe)
        {
            //setup
            const uint   CLIENTID         = 1234567890;
            const string TOKEN            = "TOKEN";
            string       EXPECTEDRESPONSE = $"HELLO {CLIENTID}";

            var testeeRef          = Sys.ActorOf(Props.Create(() => new ClientTwinActor(clientSocketProbe, authenticationProbe, defaultEndpoint, defaultShardRegionArea, defaultObjectRegionArea)));
            var clientHelloMessage = new ClientHelloMessage()
            {
                Message    = string.Empty,
                ClientId   = CLIENTID,
                ClientPort = 9999,
                Version    = Shared.Constants.Version.PROTOCOL,
            };
            var clientAuthenticationResponse = new ClientAuthenticationResponse()
            {
                AuthenticationToken = TOKEN,
            };

            //execute - client hello
            testeeRef.Tell(new UdpTransferFrame(FrameType.ClientHello, clientHelloMessage.Serialize()));

            //verify
            clientSocketProbe.ExpectMsg <Udp.Send>(s =>
            {
                var msg = new UdpTransferFrame(s.Payload.ToArray());
                Assert.Equal(FrameType.ServerAuthenticationRequest, msg.Type);
            });

            //execute - client authentication response
            testeeRef.Tell(new UdpTransferFrame(FrameType.ClientAuthenticationResponse, clientAuthenticationResponse.Serialize()));

            //verify
            authenticationProbe.ExpectMsg <RequestAuthenticationCommand>(c =>
            {
                Assert.Equal(TOKEN, c.Token);
            });

            //execute - authentication actor response
            testeeRef.Tell(new AuthenticationSuccess());

            //verify
            clientSocketProbe.ExpectMsg <Udp.Send>(s =>
            {
                var msg = new UdpTransferFrame(s.Payload.ToArray());
                Assert.Equal(FrameType.ServerHello, msg.Type);
                var serverHello = new ServerHelloMessage(msg.MessageBuffer);
                Assert.Equal(EXPECTEDRESPONSE, serverHello.Message);
                Assert.Equal(clientHelloMessage.Version, serverHello.Version);
            });

            return(testeeRef);
        }
Exemple #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ServerActor"/> class.
        /// </summary>
        /// <param name="shardCountArea">The shard count area.</param>
        /// <param name="shardCountObject">The shard count object.</param>
        /// <param name="auth0Issuer">The auth0 issuer.</param>
        /// <param name="auth0Audience">The auth0 audience.</param>
        /// <param name="signingKey">The signing key.</param>
        public ServerActor(int shardCountArea, int shardCountObject, string auth0Issuer, string auth0Audience, string signingKey)
        {
            this.state = new ServerState();
            this.state.ShardCountArea   = shardCountArea;
            this.state.ShardCountObject = shardCountObject;
            this.state.Auth0Issuer      = auth0Issuer;
            this.state.Auth0Audience    = auth0Audience;
            this.state.SigningKey       = signingKey;
            this.udpManagerActor        = Udp.Instance.Apply(Context.System).Manager;
            this.authenticationActor    = this.CreateAuthenticationActor();
            this.InitializeShardRegions(Context.System);
            this.Receive <StartServerMessage>(c =>
            {
                this.log.Info($"Binding udp on {c.ServerEndpoint}");
                this.udpManagerActor.Tell(new Udp.Bind(this.Self, c.ServerEndpoint), this.Self);
            });
            this.Receive <Terminated>(t =>
            {
                this.log.Warning($"Client {t.ActorRef.Path.Name} terminated");
                if (this.state.ClientTwinActors.ContainsKey(t.ActorRef.Path.Name))
                {
                    Context.Unwatch(this.state.ClientTwinActors[t.ActorRef.Path.Name]);
                    this.state.ClientTwinActors.Remove(t.ActorRef.Path.Name);
                }
            });
            this.Receive <RequestStateCommand>(c =>
            {
                this.RespondState(c.ReplyTo);
            });
            this.Receive <Udp.Bound>(c =>
            {
                this.log.Info($"Bound to {c.LocalAddress}");
            });
            this.Receive <Udp.Received>(c =>
            {
                IActorRef senderSocketRef = this.Sender;
                if (c.Data.Count == 0)
                {
                    this.log.Warning("Invalid message: Empty");
                    return;
                }

                var message = new UdpTransferFrame(c.Data.ToArray());
#if UDPTRACE
                // LogUdpMessage(c);
#endif
                this.ProcessClientFrame(senderSocketRef, c, message);
            });
            this.Receive <CommandFailed>(c =>
            {
                this.log.Error($"Failed command: {c.Cmd}");
            });
        }
Exemple #8
0
        public void ActorMustAcceptMessagesAfterAuthentication()
        {
            //setup
            var authenticationProbe = CreateTestProbe();
            var clientSocketProbe   = CreateTestProbe();
            var testeeRef           = CreateAuthenticatedActor(authenticationProbe, clientSocketProbe);
            var clientPingMessage   = new ClientPingMessage();

            //execute - authentication actor response
            testeeRef.Tell(new UdpTransferFrame(FrameType.ClientPing, clientPingMessage.Serialize()));

            //verify
            clientSocketProbe.ExpectMsg <Udp.Send>(s =>
            {
                var msg = new UdpTransferFrame(s.Payload.ToArray());
                Assert.Equal(FrameType.ServerPong, msg.Type);
            });
        }
Exemple #9
0
        /// <summary>Processes the message frame.</summary>
        /// <param name="frame">The frame.</param>
        /// <exception cref="ArgumentNullException">Frame is null.</exception>
        public void ProcessMessageFrame(UdpTransferFrame frame)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            using (MemoryStream memstrm = new MemoryStream(frame.MessageBuffer))
            {
                using (BinaryReader br = new BinaryReader(memstrm))
                {
                    while (memstrm.Position < memstrm.Length)
                    {
                        UdpMessage udpMessage = new UdpMessage(br);
                        this.ProcessUdpMessage(udpMessage);
                    }
                }
            }
        }
        private void ProcessUdpLoginFrame(UdpTransferFrame frame)
        {
            switch (frame.Type)
            {
            case FrameType.ClientHello:
                var msgClientHello = new ClientHelloMessage(frame.MessageBuffer);
                this.state.ClientId      = msgClientHello.ClientId;
                this.state.ClientVersion = msgClientHello.Version;
                this.RequestAuthentication();
                break;

            case FrameType.ClientAuthenticationResponse:
                var msgClientAuthenticationResponse = new ClientAuthenticationResponse(frame.MessageBuffer);
                this.AuthenticateClient(msgClientAuthenticationResponse);
                break;

            default:
                this.log.Warning($"[Client:{this.state.ClientId} => Server] not authenticated - unexpected frame type '{frame.Type}'");
                break;
            }
        }
Exemple #11
0
        /// <summary>Processes the UDP transfer frame.</summary>
        /// <param name="frame">The frame.</param>
        private void ProcessUdpTransferFrame(UdpTransferFrame frame)
        {
            switch (frame.Type)
            {
            case FrameType.ServerAuthenticationRequest:
                var msgAuthenticationRequest = new ServerAuthenticationRequest(frame.MessageBuffer);
                ProcessAuthenticationRequest(msgAuthenticationRequest, this.signingKeyBase64);
                break;

            case FrameType.ServerHello:
                SubscribeToDefaultArea();
                if (OnConnected != null)
                {
                    Thread connected = new Thread(() => OnConnected());
                    connected.Start();
                }
                break;

            case FrameType.ServerPing:
                var msgServerPing = new ServerPingMessage(frame.MessageBuffer);
                var now           = TimeSpan.FromTicks(DateTime.UtcNow.Ticks);
                var cmdClientPong = new ClientPongMessage()
                {
                    ServerRequestTimestamp = msgServerPing.ServerTimestamp, ClientRequestTimestamp = now, ClientResponseTimestamp = now
                };
                ReliableMessaging.OnSendFrame(new UdpTransferFrame(FrameType.ClientPong, cmdClientPong.Serialize()));
                break;

            case FrameType.Message:
                LastMessageReceived = DateTime.Now;
                ReliableMessaging.ProcessMessageFrame(frame);
                break;

            default:
                throw new NotImplementedException(frame.Type.ToString());
            }
        }
 private void SendFrameToClient(UdpTransferFrame frame)
 {
     this.udpSenderActor.Tell(Udp.Send.Create(ByteString.FromBytes(frame.Serialize()), this.state.Endpoint), this.Self);
 }
        private void SendFrameToClient(FrameType frameType, byte[] buffer)
        {
            var frame = new UdpTransferFrame(frameType, buffer);

            this.SendFrameToClient(frame);
        }