public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList <string> globalSupportedProtocols, IList <string> hubSupportedProtocols)
        {
            var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty <string>();

            foreach (var protocolName in supportedProtocols)
            {
                var protocol = hubProtocolResolver.GetProtocol(protocolName, (supportedProtocols as IReadOnlyList <string>) ?? supportedProtocols.ToList());
                if (protocol != null)
                {
                    _hubProtocols.Add(protocol);
                }
            }
        }
Beispiel #2
0
        internal async Task <bool> NegotiateAsync(TimeSpan timeout, IHubProtocolResolver protocolResolver, IUserIdProvider userIdProvider)
        {
            try
            {
                using (var cts = new CancellationTokenSource())
                {
                    cts.CancelAfter(timeout);
                    while (await _connectionContext.Transport.Reader.WaitToReadAsync(cts.Token))
                    {
                        while (_connectionContext.Transport.Reader.TryRead(out var buffer))
                        {
                            if (NegotiationProtocol.TryParseMessage(buffer, out var negotiationMessage))
                            {
                                var protocol = protocolResolver.GetProtocol(negotiationMessage.Protocol, this);

                                var transportCapabilities = Features.Get <IConnectionTransportFeature>()?.TransportCapabilities
                                                            ?? throw new InvalidOperationException("Unable to read transport capabilities.");

                                var dataEncoder = (protocol.Type == ProtocolType.Binary && (transportCapabilities & TransferMode.Binary) == 0)
                                    ? (IDataEncoder)Base64Encoder
                                    : PassThroughEncoder;

                                var transferModeFeature = Features.Get <ITransferModeFeature>() ??
                                                          throw new InvalidOperationException("Unable to read transfer mode.");

                                transferModeFeature.TransferMode =
                                    (protocol.Type == ProtocolType.Binary && (transportCapabilities & TransferMode.Binary) != 0)
                                        ? TransferMode.Binary
                                        : TransferMode.Text;

                                ProtocolReaderWriter = new HubProtocolReaderWriter(protocol, dataEncoder);

                                _logger.UsingHubProtocol(protocol.Name);

                                UserIdentifier = userIdProvider.GetUserId(this);

                                return(true);
                            }
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                _logger.NegotiateCanceled();
            }

            return(false);
        }
        public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList <string> globalSupportedProtocols, IList <string> hubSupportedProtocols)
        {
            var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty <string>();

            foreach (var protocolName in supportedProtocols)
            {
                // blazorpack is meant to only be used by the ComponentHub
                // We remove it from the list here except when the Hub has a single protocol that is "blazorpack" because
                // that identifies it as the ComponentHub
                if (supportedProtocols.Count > 1 && string.Equals(protocolName, "blazorpack", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var protocol = hubProtocolResolver.GetProtocol(protocolName, (supportedProtocols as IReadOnlyList <string>) ?? supportedProtocols.ToList());
                if (protocol != null)
                {
                    _hubProtocols.Add(protocol);
                }
            }
        }
Beispiel #4
0
        internal async Task <bool> NegotiateAsync(TimeSpan timeout, IList <string> supportedProtocols, IHubProtocolResolver protocolResolver, IUserIdProvider userIdProvider)
        {
            try
            {
                using (var cts = new CancellationTokenSource())
                {
                    cts.CancelAfter(timeout);

                    while (true)
                    {
                        var result = await _connectionContext.Transport.Input.ReadAsync(cts.Token);

                        var buffer   = result.Buffer;
                        var consumed = buffer.End;
                        var examined = buffer.End;

                        try
                        {
                            if (!buffer.IsEmpty)
                            {
                                if (NegotiationProtocol.TryParseMessage(buffer, out var negotiationMessage, out consumed, out examined))
                                {
                                    Protocol = protocolResolver.GetProtocol(negotiationMessage.Protocol, supportedProtocols, this);

                                    // If there's a transfer format feature, we need to check if we're compatible and set the active format.
                                    // If there isn't a feature, it means that the transport supports binary data and doesn't need us to tell them
                                    // what format we're writing.
                                    var transferFormatFeature = Features.Get <ITransferFormatFeature>();
                                    if (transferFormatFeature != null)
                                    {
                                        if ((transferFormatFeature.SupportedFormats & Protocol.TransferFormat) == 0)
                                        {
                                            throw new InvalidOperationException($"Cannot use the '{Protocol.Name}' protocol on the current transport. The transport does not support the '{Protocol.TransferFormat}' transfer mode.");
                                        }

                                        transferFormatFeature.ActiveFormat = Protocol.TransferFormat;
                                    }

                                    _cachedPingMessage = Protocol.WriteToArray(PingMessage.Instance);

                                    Log.UsingHubProtocol(_logger, Protocol.Name);

                                    UserIdentifier = userIdProvider.GetUserId(this);

                                    if (Features.Get <IConnectionInherentKeepAliveFeature>() == null)
                                    {
                                        // Only register KeepAlive after protocol negotiated otherwise KeepAliveTick could try to write without having a ProtocolReaderWriter
                                        Features.Get <IConnectionHeartbeatFeature>()?.OnHeartbeat(state => ((HubConnectionContext)state).KeepAliveTick(), this);
                                    }

                                    return(true);
                                }
                            }
                            else if (result.IsCompleted)
                            {
                                break;
                            }
                        }
                        finally
                        {
                            _connectionContext.Transport.Input.AdvanceTo(consumed, examined);
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Log.NegotiateCanceled(_logger);
            }

            return(false);
        }
Beispiel #5
0
        internal async Task <bool> NegotiateAsync(TimeSpan timeout, IList <string> supportedProtocols, IHubProtocolResolver protocolResolver, IUserIdProvider userIdProvider)
        {
            try
            {
                using (var cts = new CancellationTokenSource())
                {
                    cts.CancelAfter(timeout);

                    while (true)
                    {
                        var result = await _connectionContext.Transport.Input.ReadAsync(cts.Token);

                        var buffer   = result.Buffer;
                        var consumed = buffer.End;
                        var examined = buffer.End;

                        try
                        {
                            if (!buffer.IsEmpty)
                            {
                                if (NegotiationProtocol.TryParseMessage(buffer, out var negotiationMessage, out consumed, out examined))
                                {
                                    var protocol = protocolResolver.GetProtocol(negotiationMessage.Protocol, supportedProtocols, this);

                                    var transportCapabilities = Features.Get <IConnectionTransportFeature>()?.TransportCapabilities
                                                                ?? throw new InvalidOperationException("Unable to read transport capabilities.");

                                    var dataEncoder = (protocol.Type == ProtocolType.Binary && (transportCapabilities & TransferMode.Binary) == 0)
                                        ? (IDataEncoder)Base64Encoder
                                        : PassThroughEncoder;

                                    var transferModeFeature = Features.Get <ITransferModeFeature>() ??
                                                              throw new InvalidOperationException("Unable to read transfer mode.");

                                    transferModeFeature.TransferMode =
                                        (protocol.Type == ProtocolType.Binary && (transportCapabilities & TransferMode.Binary) != 0)
                                            ? TransferMode.Binary
                                            : TransferMode.Text;

                                    ProtocolReaderWriter = new HubProtocolReaderWriter(protocol, dataEncoder);
                                    _cachedPingMessage   = ProtocolReaderWriter.WriteMessage(PingMessage.Instance);

                                    Log.UsingHubProtocol(_logger, protocol.Name);

                                    UserIdentifier = userIdProvider.GetUserId(this);

                                    if (Features.Get <IConnectionInherentKeepAliveFeature>() == null)
                                    {
                                        // Only register KeepAlive after protocol negotiated otherwise KeepAliveTick could try to write without having a ProtocolReaderWriter
                                        Features.Get <IConnectionHeartbeatFeature>()?.OnHeartbeat(state => ((HubConnectionContext)state).KeepAliveTick(), this);
                                    }

                                    return(true);
                                }
                            }
                            else if (result.IsCompleted)
                            {
                                break;
                            }
                        }
                        finally
                        {
                            _connectionContext.Transport.Input.AdvanceTo(consumed, examined);
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Log.NegotiateCanceled(_logger);
            }

            return(false);
        }
Beispiel #6
0
 private IHubProtocol GetProtocol()
 {
     return(_options.ProtocolType == ProtocolType.Text
         ? _protocolResolver.GetProtocol("json", null)
         : _protocolResolver.GetProtocol("messagepack", null));
 }