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); } } }
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); } } }
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); }
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); }
private IHubProtocol GetProtocol() { return(_options.ProtocolType == ProtocolType.Text ? _protocolResolver.GetProtocol("json", null) : _protocolResolver.GetProtocol("messagepack", null)); }