예제 #1
0
        private async Task DispatchMessagesAsync(HubConnectionContext connection)
        {
            var input    = connection.Input;
            var protocol = connection.Protocol;

            var binder = new HubConnectionBinder <THub>(_dispatcher, connection);

            while (true)
            {
                var result = await input.ReadAsync();

                var buffer = result.Buffer;

                try
                {
                    if (result.IsCanceled)
                    {
                        break;
                    }

                    if (!buffer.IsEmpty)
                    {
                        connection.ResetClientTimeout();

                        while (protocol.TryParseMessage(ref buffer, binder, out var message))
                        {
                            await _dispatcher.DispatchMessageAsync(connection, message);
                        }
                    }

                    if (result.IsCompleted)
                    {
                        if (!buffer.IsEmpty)
                        {
                            throw new InvalidDataException("Connection terminated while reading a message.");
                        }
                        break;
                    }
                }
                finally
                {
                    // The buffer was sliced up to where it was consumed, so we can just advance to the start.
                    // We mark examined as buffer.End so that if we didn't receive a full frame, we'll wait for more data
                    // before yielding the read again.
                    input.AdvanceTo(buffer.Start, buffer.End);
                }
            }
        }
예제 #2
0
        private async Task DispatchMessagesAsync(HubConnectionContext connection)
        {
            var input    = connection.Input;
            var protocol = connection.Protocol;

            connection.BeginClientTimeout();


            var binder = new HubConnectionBinder <THub>(_dispatcher, connection);

            while (true)
            {
                var result = await input.ReadAsync();

                var buffer = result.Buffer;

                try
                {
                    if (result.IsCanceled)
                    {
                        break;
                    }

                    if (!buffer.IsEmpty)
                    {
                        bool messageReceived = false;
                        // No message limit, just parse and dispatch
                        if (_maximumMessageSize == null)
                        {
                            while (protocol.TryParseMessage(ref buffer, binder, out var message))
                            {
                                messageReceived = true;
                                connection.StopClientTimeout();
                                await _dispatcher.DispatchMessageAsync(connection, message);
                            }

                            if (messageReceived)
                            {
                                connection.BeginClientTimeout();
                            }
                        }
                        else
                        {
                            // We give the parser a sliding window of the default message size
                            var maxMessageSize = _maximumMessageSize.Value;

                            while (!buffer.IsEmpty)
                            {
                                var segment    = buffer;
                                var overLength = false;

                                if (segment.Length > maxMessageSize)
                                {
                                    segment    = segment.Slice(segment.Start, maxMessageSize);
                                    overLength = true;
                                }

                                if (protocol.TryParseMessage(ref segment, binder, out var message))
                                {
                                    messageReceived = true;
                                    connection.StopClientTimeout();

                                    await _dispatcher.DispatchMessageAsync(connection, message);
                                }
                                else if (overLength)
                                {
                                    throw new InvalidDataException($"The maximum message size of {maxMessageSize}B was exceeded. The message size can be configured in AddHubOptions.");
                                }
                                else
                                {
                                    // No need to update the buffer since we didn't parse anything
                                    break;
                                }

                                // Update the buffer to the remaining segment
                                buffer = buffer.Slice(segment.Start);
                            }

                            if (messageReceived)
                            {
                                connection.BeginClientTimeout();
                            }
                        }
                    }