public async Task <ConnectionContext> ConnectAsync(TransferFormat transferFormat, string connectionId, string target, CancellationToken cancellationToken = default) { var httpConnectionOptions = new HttpConnectionOptions { Url = GetServiceUrl(connectionId, target), AccessTokenProvider = () => Task.FromResult(_provider.GenerateServerAccessToken(_hubName, _userId)), Transports = HttpTransportType.WebSockets, SkipNegotiation = true, Headers = CustomHeader }; var httpConnection = new HttpConnection(httpConnectionOptions, _loggerFactory); try { await httpConnection.StartAsync(transferFormat); return(httpConnection); } catch { await httpConnection.DisposeAsync(); throw; } }
private async Task StartAsyncCore(TransferFormat transferFormat) { CheckDisposed(); if (_started) { Log.SkippingStart(_logger); return; } await _connectionLock.WaitAsync(); try { CheckDisposed(); if (_started) { Log.SkippingStart(_logger); return; } Log.Starting(_logger); await SelectAndStartTransport(transferFormat); _started = true; Log.Started(_logger); } finally { _connectionLock.Release(); } }
public async Task LongPollingTransportSetsTransferFormat(TransferFormat transferFormat) { var mockHttpHandler = new Mock <HttpMessageHandler>(); mockHttpHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) => { await Task.Yield(); return(ResponseUtils.CreateResponse(HttpStatusCode.OK)); }); using (var httpClient = new HttpClient(mockHttpHandler.Object)) { var longPollingTransport = new LongPollingTransport(httpClient); try { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); await longPollingTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, transferFormat, connection : new TestConnection()); } finally { await longPollingTransport.StopAsync(); } } }
public async Task LongPollingTransportSetsTransferFormat(TransferFormat transferFormat) { var mockHttpHandler = new Mock <HttpMessageHandler>(); mockHttpHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) => { await Task.Yield(); return(ResponseUtils.CreateResponse(HttpStatusCode.OK)); }); using (var httpClient = new HttpClient(mockHttpHandler.Object)) { var longPollingTransport = new LongPollingTransport(httpClient); try { await longPollingTransport.StartAsync(TestUri, transferFormat); } finally { await longPollingTransport.StopAsync(); } } }
[InlineData((TransferFormat)42)] // Unexpected value public async Task SSETransportThrowsForInvalidTransferFormat(TransferFormat transferFormat) { var mockHttpHandler = new Mock <HttpMessageHandler>(); mockHttpHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns <HttpRequestMessage, CancellationToken>(async(request, cancellationToken) => { await Task.Yield(); return(new HttpResponseMessage { Content = new StringContent(string.Empty) }); }); using (var httpClient = new HttpClient(mockHttpHandler.Object)) using (StartVerifiableLog()) { var sseTransport = new ServerSentEventsTransport(httpClient, LoggerFactory); var exception = await Assert.ThrowsAsync <ArgumentException>(() => sseTransport.StartAsync(new Uri("http://fakeuri.org"), transferFormat)); Assert.Contains($"The '{transferFormat}' transfer format is not supported by this transport.", exception.Message); Assert.Equal("transferFormat", exception.ParamName); } }
public async Task StartAsync(Uri url, IDuplexPipe application, TransferFormat transferFormat, IConnection connection) { if (url == null) { throw new ArgumentNullException(nameof(url)); } if (application == null) { throw new ArgumentNullException(nameof(application)); } if (transferFormat != TransferFormat.Binary && transferFormat != TransferFormat.Text) { throw new ArgumentException($"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } _application = application; _webSocketMessageType = transferFormat == TransferFormat.Binary ? WebSocketMessageType.Binary : WebSocketMessageType.Text; Log.StartTransport(_logger, transferFormat); await Connect(url); // TODO: Handle TCP connection errors // https://github.com/SignalR/SignalR/blob/1fba14fa3437e24c204dfaf8a18db3fce8acad3c/src/Microsoft.AspNet.SignalR.Core/Owin/WebSockets/WebSocketHandler.cs#L248-L251 Running = ProcessSocketAsync(_webSocket); }
public Task StartAsync(Uri url, IDuplexPipe application, TransferFormat transferFormat, IConnection connection) { if (transferFormat != TransferFormat.Text) { throw new ArgumentException($"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } _application = application; Log.StartTransport(_logger, transferFormat); var sendTask = SendUtils.SendMessages(url, _application, _httpClient, _httpOptions, _transportCts, _logger); var receiveTask = OpenConnection(_application, url, _transportCts.Token); Running = Task.WhenAll(sendTask, receiveTask).ContinueWith(t => { Log.TransportStopped(_logger, t.Exception?.InnerException); _application.Output.Complete(t.Exception?.InnerException); _application.Input.Complete(); return(t); }).Unwrap(); return(Task.CompletedTask); }
public Task <ConnectionContext> ConnectAsync(HubServiceEndpoint endpoint, TransferFormat transferFormat, string connectionId, string target, CancellationToken cancellationToken = default, IDictionary <string, string> headers = null) { var connection = new TestConnectionContext(); _waitForServerConnection.TrySetResult(connection); return(Task.FromResult <ConnectionContext>(connection)); }
private Task StartAsyncCore(TransferFormat transferFormat) { if (ChangeState(from: ConnectionState.Disconnected, to: ConnectionState.Connecting) != ConnectionState.Disconnected) { return(Task.FromException( new InvalidOperationException($"Cannot start a connection that is not in the {nameof(ConnectionState.Disconnected)} state."))); } _startTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); _eventQueue = new TaskQueue(); StartAsyncInternal(transferFormat) .ContinueWith(t => { var abortException = _abortException; if (t.IsFaulted || abortException != null) { _startTcs.SetException(_abortException ?? t.Exception.InnerException); } else if (t.IsCanceled) { _startTcs.SetCanceled(); } else { _startTcs.SetResult(null); } }); return(_startTcs.Task); }
public async Task StartAsync(Uri url, TransferFormat transferFormat) { if (transferFormat != TransferFormat.Binary && transferFormat != TransferFormat.Text) { throw new ArgumentException($"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } Log.StartTransport(_logger, transferFormat); // Make initial long polling request // Server uses first long polling request to finish initializing connection and it returns without data var request = new HttpRequestMessage(HttpMethod.Get, url); using (var response = await _httpClient.SendAsync(request)) { response.EnsureSuccessStatusCode(); } // Create the pipe pair (Application's writer is connected to Transport's reader, and vice versa) var options = ClientPipeOptions.DefaultOptions; var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; Running = ProcessAsync(url); }
public Task StartAsync(Uri url, TransferFormat transferFormat, CancellationToken cancellationToken) { if (transferFormat != TransferFormat.Text) { throw new ArgumentException( $"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } Log.StartTransport(_logger, transferFormat); // Create pipe PipeOptions options = ClientPipeOptions.DefaultOptions; DuplexPipe.DuplexPipePair pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; CancellationTokenSource inputCts = new CancellationTokenSource(); _application.Input.OnWriterCompleted((exception, state) => ((CancellationTokenSource)state).Cancel(), inputCts); // Start streams Running = ProcessAsync(url, inputCts.Token); return(Task.CompletedTask); }
private static HttpConnection CreateConnection( HttpConnectionOptions httpConnectionOptions, ILoggerFactory loggerFactory = null, ITransport transport = null, ITransportFactory transportFactory = null, TransferFormat transferFormat = TransferFormat.Text) { loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; httpConnectionOptions.Url ??= new Uri("http://fakeuri.org/"); httpConnectionOptions.DefaultTransferFormat = transferFormat; if (transportFactory == null && transport != null) { transportFactory = new TestTransportFactory(transport); } if (transportFactory != null) { return(new HttpConnection(httpConnectionOptions, loggerFactory, transportFactory)); } else { // Use the public constructor to get the default transport factory. return(new HttpConnection(httpConnectionOptions, loggerFactory)); } }
public Task StartAsync(Uri url, TransferFormat transferFormat) { var options = ClientPipeOptions.DefaultOptions; var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; _tries++; Assert.True(QueryHelpers.ParseQuery(url.Query).TryGetValue("id", out var id)); if (_prevConnectionId == null) { _prevConnectionId = id; } else { Assert.True(_prevConnectionId != id); _prevConnectionId = id; } if (_tries < availableTransports) { return(Task.FromException(new Exception())); } else { return(Task.CompletedTask); } }
public async Task <ConnectionContext> ConnectAsync(HubServiceEndpoint hubServiceEndpoint, TransferFormat transferFormat, string connectionId, string target, CancellationToken cancellationToken = default, IDictionary <string, string> headers = null) { var provider = hubServiceEndpoint.Provider; var hubName = hubServiceEndpoint.Hub; Task <string> accessTokenGenerater() => provider.GenerateServerAccessTokenAsync(hubName, _userId); var url = GetServiceUrl(provider, hubName, connectionId, target); var connectionOptions = new WebSocketConnectionOptions { Headers = headers, Proxy = provider.Proxy, }; var connection = new WebSocketConnectionContext(connectionOptions, _loggerFactory, accessTokenGenerater); try { await connection.StartAsync(url, cancellationToken); return(connection); } catch { await connection.StopAsync(); throw; } }
public Task <ConnectionContext> ConnectAsync(HubServiceEndpoint endpoint, TransferFormat transferFormat, string connectionId, string target, CancellationToken cancellationToken = default, IDictionary <string, string> headers = null) { // ConnectAsync merely means establish a physical connection. // In our case this means connect the pipes and start the message processing loops ConnectionContext c = new MockServiceConnectionContext(_mockService, endpoint, target, connectionId); return(Task.FromResult(c)); }
public WebSocketsTransport(IDuplexPipe pipe, WebSocketOptions options, ILogger logger) { this.pipe = pipe; this.options = options; this.logger = logger; cancellation = new CancellationTokenSource(); transferFormat = TransferFormat.Binary; }
public static void StartTransport(ILogger?logger, TransferFormat transferFormat) { if (logger is null) { return; } StartTransportMessage(logger, transferFormat, null); }
public Task StartAsync(Uri url, IDuplexPipe application, TransferFormat transferFormat, IConnection connection) { _application = application; Action <Exception, object> onCompletedCallback = (ex, tcs) => { ((TaskCompletionSource <object>)tcs).TrySetResult(null); }; _application.Input.OnWriterCompleted(onCompletedCallback, _writerTcs); _application.Output.OnReaderCompleted(onCompletedCallback, _readerTcs); throw new Exception(); }
public Task <ConnectionContext> ConnectAsync(TransferFormat transferFormat, string connectionId, string hubName, CancellationToken cancellationToken = default) { var connection = new TestConnectionContext(); _connectCallback?.Invoke(connection); _waitForServerConnection.TrySetResult(connection); return(Task.FromResult <ConnectionContext>(connection)); }
public Task StartAsync(Uri url, IDuplexPipe application, TransferFormat transferFormat, IConnection connection) { if ((Format & transferFormat) == 0) { throw new InvalidOperationException($"The '{transferFormat}' transfer format is not supported by this transport."); } Application = application; return(_startHandler()); }
public static void TransportDoesNotSupportTransferFormat(ILogger logger, HttpTransportType transport, TransferFormat transferFormat) { if (!logger.IsEnabled(LogLevel.Debug)) { return; } _transportDoesNotSupportTransferFormat(logger, transport.ToString(), transferFormat.ToString(), (Exception)null); }
public async Task StartAsync(Uri url, TransferFormat transferFormat) { if (url == null) { throw new ArgumentNullException(nameof(url)); } if (transferFormat != TransferFormat.Binary && transferFormat != TransferFormat.Text) { throw new ArgumentException($"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } _webSocketMessageType = transferFormat == TransferFormat.Binary ? WebSocketMessageType.Binary : WebSocketMessageType.Text; var resolvedUrl = ResolveWebSocketsUrl(url); // We don't need to capture to a local because we never change this delegate. if (_accessTokenProvider != null) { var accessToken = await _accessTokenProvider(); if (!string.IsNullOrEmpty(accessToken)) { _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}"); } } Log.StartTransport(_logger, transferFormat, resolvedUrl); try { await _webSocket.ConnectAsync(resolvedUrl, CancellationToken.None); } catch { _webSocket.Dispose(); throw; } Log.StartedTransport(_logger); // Create the pipe pair (Application's writer is connected to Transport's reader, and vice versa) var options = ClientPipeOptions.DefaultOptions; var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; // TODO: Handle TCP connection errors // https://github.com/SignalR/SignalR/blob/1fba14fa3437e24c204dfaf8a18db3fce8acad3c/src/Microsoft.AspNet.SignalR.Core/Owin/WebSockets/WebSocketHandler.cs#L248-L251 Running = ProcessSocketAsync(_webSocket); }
public static Task StartAsync(this IDuplexPipe pipe, Uri uri, TransferFormat transferFormat) { #pragma warning disable CA1062 var method = pipe.GetType().GetMethod( nameof(StartAsync), new Type[] { typeof(Uri), typeof(TransferFormat), typeof(CancellationToken) }); #pragma warning restore CA1062 Debug.Assert(method != null); var result = method !.Invoke(pipe, new object[] { uri, transferFormat, default(CancellationToken) }) as Task; Debug.Assert(result != null); return(result !); }
public async Task WebSocketsTransportThrowsForInvalidTransferFormat(TransferFormat transferFormat) { using (StartVerifiableLog(out var loggerFactory)) { var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory, accessTokenProvider: null); var exception = await Assert.ThrowsAsync <ArgumentException>(() => webSocketsTransport.StartAsync(new Uri("http://fakeuri.org"), transferFormat)); Assert.Contains($"The '{transferFormat}' transfer format is not supported by this transport.", exception.Message); Assert.Equal("transferFormat", exception.ParamName); } }
public void ValidHash() { using (var mem = new MemoryStream()) { var messages = GenerateMessages(7); TransferFormat.WriteMessages(messages, mem); mem.Seek(0, SeekOrigin.Begin); var actual = TransferFormat.ReadMessages(mem); AssertEqual(messages, actual); } }
public async Task WebSocketsTransportThrowsForInvalidTransferFormat(TransferFormat transferFormat) { using (StartLog(out var loggerFactory)) { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory); var exception = await Assert.ThrowsAsync <ArgumentException>(() => webSocketsTransport.StartAsync(new Uri("http://fakeuri.org"), pair.Application, transferFormat, connection: Mock.Of <IConnection>())); Assert.Contains($"The '{transferFormat}' transfer format is not supported by this transport.", exception.Message); Assert.Equal("transferFormat", exception.ParamName); } }
public async Task StartAsync(TransferFormat transferFormat) { _started.TrySetResult(null); await _onStart(); if (_autoHandshake) { // We can't await this as it will block StartAsync which will block // HubConnection.StartAsync which sends the Handshake in the first place! _ = ReadHandshakeAndSendResponseAsync(); } }
public async Task WebSocketsTransportSetsTransferFormat(TransferFormat transferFormat) { using (StartVerifiableLog(out var loggerFactory)) { var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: loggerFactory, accessTokenProvider: null); await webSocketsTransport.StartAsync(new Uri(ServerFixture.WebSocketsUrl + "/echo"), transferFormat).OrTimeout(); await webSocketsTransport.StopAsync().OrTimeout(); await webSocketsTransport.Running.OrTimeout(); } }
public async Task WebSocketsTransportSetsTransferFormat(TransferFormat transferFormat) { using (StartLog(out var loggerFactory)) { var webSocketsTransport = new WebSocketsTransport(httpOptions: null, loggerFactory: loggerFactory); await webSocketsTransport.StartAsync(new Uri(_serverFixture.WebSocketsUrl + "/echo"), transferFormat).OrTimeout(); await webSocketsTransport.StopAsync().OrTimeout(); await webSocketsTransport.Running.OrTimeout(); } }
public async Task WebSocketsTransportSetsTransferFormat(TransferFormat transferFormat) { await using (var server = await StartServer <Startup>()) { var webSocketsTransport = new WebSocketsTransport(httpConnectionOptions: null, loggerFactory: LoggerFactory, accessTokenProvider: null); await webSocketsTransport.StartAsync(new Uri(server.WebSocketsUrl + "/echo"), transferFormat).DefaultTimeout(); await webSocketsTransport.StopAsync().DefaultTimeout(); await webSocketsTransport.Running.DefaultTimeout(); } }