Ejemplo n.º 1
0
        private async Task ServiceStatusPingAsync(TimerAwaitable timer)
        {
            using (timer)
            {
                timer.Start();

                while (await timer)
                {
                    try
                    {
                        // Check if last send time is longer than default keep-alive ticks and then send ping
                        if (Stopwatch.GetTimestamp() - Interlocked.Read(ref _lastSendTimestamp) > DefaultGetServiceStatusTicks)
                        {
                            await WriteAsync(RuntimeServicePingMessage.GetStatusPingMessage(true));

                            Interlocked.Exchange(ref _lastSendTimestamp, Stopwatch.GetTimestamp());
                            Log.SentServiceStatusPing(Logger);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.FailedSendingServiceStatusPing(Logger, e);
                    }
                }
            }
        }
Ejemplo n.º 2
0
 public Task WriteAsync(ServiceMessage serviceMessage)
 {
     if (RuntimeServicePingMessage.IsFin(serviceMessage))
     {
         _offline.SetResult(true);
     }
     return(Task.CompletedTask);
 }
Ejemplo n.º 3
0
        public override Task HandlePingAsync(PingMessage pingMessage)
        {
            if (RuntimeServicePingMessage.TryGetStatus(pingMessage, out var status))
            {
                _active = GetServiceStatus(status, CheckWindow, CheckTimeSpan);
                Log.ReceivedServiceStatusPing(Logger, status, Endpoint);
            }

            return(Task.CompletedTask);
        }
Ejemplo n.º 4
0
        private async Task MockServiceAsync(TestServiceConnectionForCloseAsync conn)
        {
            IServiceProtocol proto = new ServiceProtocol();

            await conn.ConnectionCreated;

            // open 2 new connections (to create 2 new outgoing tasks
            proto.WriteMessage(new OpenConnectionMessage(Guid.NewGuid().ToString(), new Claim[0]), conn.Application.Output);
            proto.WriteMessage(new OpenConnectionMessage(Guid.NewGuid().ToString(), new Claim[0]), conn.Application.Output);
            await conn.Application.Output.FlushAsync();

            while (true)
            {
                var result = await conn.Application.Input.ReadAsync();

                var buffer = result.Buffer;

                try
                {
                    // write back a FinAck after receiving a Fin
                    if (proto.TryParseMessage(ref buffer, out ServiceMessage message))
                    {
                        if (RuntimeServicePingMessage.IsFin(message))
                        {
                            var pong = RuntimeServicePingMessage.GetFinAckPingMessage();
                            proto.WriteMessage(pong, conn.Application.Output);
                            await conn.Application.Output.FlushAsync();

                            break;
                        }
                    }
                }
                finally
                {
                    conn.Application.Input.AdvanceTo(buffer.Start, buffer.End);
                }
            }
        }
Ejemplo n.º 5
0
        public void Start()
        {
            _processIncoming = Task.Run(async() =>
            {
                try
                {
                    while (true)
                    {
                        var result = _lastReadResult = await MockServicePipe.Input.ReadAsync();
                        if (result.IsCanceled || result.IsCompleted)
                        {
                            break;
                        }

                        var buffer = result.Buffer;

                        try
                        {
                            if (!buffer.IsEmpty)
                            {
                                while (_servicePro.TryParseMessage(ref buffer, out var message))
                                {
                                    // always enqueue so tests can peek and analyze any of these messages
                                    EnqueueMessage(message);

                                    // now react to some of the connection related stuff
                                    if (message is HandshakeRequestMessage)
                                    {
                                        var handshakeResponse = new HandshakeResponseMessage("");
                                        _servicePro.WriteMessage(handshakeResponse, MockServicePipe.Output);
                                        var flushResult = _lastFlushResult = await MockServicePipe.Output.FlushAsync();

                                        if (flushResult.IsCanceled || flushResult.IsCompleted)
                                        {
                                            _completedHandshake.TrySetResult(false);
                                        }
                                        else
                                        {
                                            // sending ack merely allows SDK side to proceed with establishing the connection
                                            // for this service connection to become available for hubs to send messages
                                            // we'd need to wait for SDK side service connection to change its status
                                            _completedHandshake.TrySetResult(true);
                                        }
                                        continue;
                                    }
                                    else if (message is ConnectionDataMessage cdm)
                                    {
                                        var payload = cdm.Payload;

                                        // do we know this client?
                                        var clientConnection = ClientConnections.Where(c => c.ConnectionId == cdm.ConnectionId).FirstOrDefault();
                                        if (clientConnection != null)
                                        {
                                            // is this client expecting handshake response?
                                            if (clientConnection.ExpectsClientHandshake)
                                            {
                                                // todo: maybe try parse first and then check if handshake is expected?
                                                if (HandshakeProtocol.TryParseResponseMessage(ref payload, out var response))
                                                {
                                                    clientConnection.ExpectsClientHandshake = false;
                                                    clientConnection.HandshakeCompleted.TrySetResult(response.Error);
                                                }
                                            }

                                            // There is no such goal to provide full message parsing capabilities here
                                            // But it is useful to know the hub invocation return result in some tests so there we have it.
                                            while (_signalRPro.TryParseMessage(ref payload, MockSvc.CurrentInvocationBinder, out HubMessage hubMessage))
                                            {
                                                clientConnection.EnqueueMessage(hubMessage);

                                                if (hubMessage is CloseMessage closeMsg)
                                                {
                                                    clientConnection.CloseMessageReceivedFromSdk = true;
                                                }
                                            }
                                        }
                                    }
                                    else if (message is ServicePingMessage ping && ping.IsFin())
                                    {
                                        var pong = RuntimeServicePingMessage.GetFinAckPingMessage();
                                        _servicePro.WriteMessage(pong, MockServicePipe.Output);
                                        var flushResult = _lastFlushResult = await MockServicePipe.Output.FlushAsync();

                                        //todo: do we care about this flush result?
                                    }
                                }
                            }
                        }
                        finally
                        {
                            MockServicePipe.Input.AdvanceTo(buffer.Start, buffer.End);
                        }
                    }
                }
                catch (Exception e)
                {
                    _processIncomingException = e;
                }
            });
        }