private static HandshakeResponseMessage CreateHandshakeResponseMessage(ref MessagePackReader reader, int arrayLength)
        {
            var errorMessage = ReadString(ref reader, "errorMessage");
            var result       = new HandshakeResponseMessage(errorMessage);

            if (arrayLength >= 3)
            {
                result.ReadExtensionMembers(ref reader);
            }
            return(result);
        }
Beispiel #2
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;
                }
            });
        }
 private static void WriteHandshakeResponseMessage(ref MessagePackWriter writer, HandshakeResponseMessage message)
 {
     writer.WriteArrayHeader(2);
     writer.Write(ServiceProtocolConstants.HandshakeResponseType);
     writer.Write(message.ErrorMessage);
 }