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 }); } }
/// <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); }
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); }
/// <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}"); }); }
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); }); }
/// <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; } }
/// <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); }