private static async Task RunAsync() { var cts = new CancellationTokenSource(); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key); var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider); listener.Connecting += (o, e) => { Console.WriteLine("Connecting ..."); }; listener.Offline += (o, e) => { Console.WriteLine("Offine"); }; listener.Online += (o, e) => { Console.WriteLine("Onine"); }; await listener.OpenAsync(cts.Token); Console.WriteLine("Server Listening ..."); cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start(); while (true) { var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } ProcessMessagesOnConnection(relayConnection, cts); } await listener.CloseAsync(cts.Token); }
async Task ListenerShutdownWithPendingAcceptsTest(EndpointTestType endpointTestType) { HybridConnectionListener listener = null; try { listener = GetHybridConnectionListener(endpointTestType); var client = GetHybridConnectionClient(endpointTestType); TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(20)); var acceptTasks = new List <Task <HybridConnectionStream> >(600); TestUtility.Log($"Calling listener.AcceptConnectionAsync() {acceptTasks.Capacity} times"); for (int i = 0; i < acceptTasks.Capacity; i++) { acceptTasks.Add(listener.AcceptConnectionAsync()); Assert.False(acceptTasks[i].IsCompleted); } TestUtility.Log($"Closing {listener}"); await listener.CloseAsync(TimeSpan.FromSeconds(10)); listener = null; for (int i = 0; i < acceptTasks.Count; i++) { Assert.True(acceptTasks[i].Wait(TimeSpan.FromSeconds(5))); Assert.Null(acceptTasks[i].Result); } } finally { await this.SafeCloseAsync(listener); } }
private static async Task RunAsync() { var cts = new CancellationTokenSource(); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key); var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider); // Subscribe to the status events listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); }; listener.Offline += (o, e) => { Console.WriteLine("Offline"); }; listener.Online += (o, e) => { Console.WriteLine("Online"); }; // Establish the control channel to the Azure Relay service await listener.OpenAsync(cts.Token); Console.WriteLine("Server listening"); // Providing callback for cancellation token that will close the listener. cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); // Start a new thread that will continuously read the console. new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start(); // Accept the next available, pending connection request. while (true) { var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } ProcessMessagesOnConnection(relayConnection, cts); } // Close the listener after we exit the processing loop await listener.CloseAsync(cts.Token); }
public void Start() { _log.Information("Relay: {idx}:{relay}. Opening relay listener connection", _forwarderIdx, _relayListener.Address); try { _relayListener.OpenAsync(CancellationToken.None).GetAwaiter().GetResult(); _relayListener.AcceptConnectionAsync().ContinueWith(StreamAccepted); } catch (Exception e) { _log.Error(e, "Relay: {idx}:{relay}. Unable to connect", _forwarderIdx, _relayListener.Address); throw; } }
async Task RawWebSocketSenderTest(EndpointTestType endpointTestType) { HybridConnectionListener listener = null; try { listener = GetHybridConnectionListener(endpointTestType); var clientWebSocket = new ClientWebSocket(); var wssUri = await GetWebSocketConnectionUri(endpointTestType); using (var cancelSource = new CancellationTokenSource(TimeSpan.FromMinutes(1))) { TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(cancelSource.Token); await clientWebSocket.ConnectAsync(wssUri, cancelSource.Token); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log("Client and Listener are connected!"); Assert.Null(clientWebSocket.SubProtocol); byte[] sendBuffer = this.CreateBuffer(1024, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); await clientWebSocket.SendAsync(new ArraySegment <byte>(sendBuffer), WebSocketMessageType.Binary, true, cancelSource.Token); TestUtility.Log($"clientWebSocket wrote {sendBuffer.Length} bytes"); byte[] readBuffer = new byte[sendBuffer.Length]; await this.ReadCountBytesAsync(listenerStream, readBuffer, 0, readBuffer.Length, TimeSpan.FromSeconds(30)); Assert.Equal(sendBuffer, readBuffer); TestUtility.Log("Calling clientStream.CloseAsync"); var clientStreamCloseTask = clientWebSocket.CloseAsync(WebSocketCloseStatus.EndpointUnavailable, "From Test Code", cancelSource.Token); TestUtility.Log("Reading from listenerStream"); int bytesRead = await this.SafeReadAsync(listenerStream, readBuffer, 0, readBuffer.Length); TestUtility.Log($"listenerStream.Read returned {bytesRead} bytes"); Assert.Equal(0, bytesRead); TestUtility.Log("Calling listenerStream.CloseAsync"); var listenerStreamCloseTask = listenerStream.CloseAsync(cancelSource.Token); await listenerStreamCloseTask; TestUtility.Log("Calling listenerStream.CloseAsync completed"); await clientStreamCloseTask; TestUtility.Log("Calling clientStream.CloseAsync completed"); TestUtility.Log($"Closing {listener}"); await listener.CloseAsync(TimeSpan.FromSeconds(10)); listener = null; } } finally { await this.SafeCloseAsync(listener); } }
public async Task <bool> OpenService() { try { await relayListener.OpenAsync(CancellationToken.None); #pragma warning disable 4014 relayListener.AcceptConnectionAsync().ContinueWith(t => StreamAccepted(t.Result)); #pragma warning restore 4014 } catch (Exception e) { Trace.TraceError("Unable to connect: {0}", e.Message); return(false); } return(true); }
async Task WriteLargeDataSetTest(EndpointTestType endpointTestType, int kilobytesToSend = 1024) { HybridConnectionListener listener = null; try { listener = GetHybridConnectionListener(endpointTestType); var client = GetHybridConnectionClient(endpointTestType); TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(30)); var clientStream = await client.CreateConnectionAsync(); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log($"clientStream and listenerStream connected! {listenerStream}"); byte[] sendBuffer = this.CreateBuffer(kilobytesToSend * 1024, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); byte[] readBuffer = new byte[sendBuffer.Length]; TestUtility.Log($"Sending {sendBuffer.Length} bytes from client->listener"); var sendTask = clientStream.WriteAsync(sendBuffer, 0, sendBuffer.Length); var readTask = this.ReadCountBytesAsync(listenerStream, readBuffer, 0, readBuffer.Length, TimeSpan.FromSeconds(30)); await Task.WhenAll(sendTask, readTask); TestUtility.Log($"Sending and Reading complete"); Assert.Equal(sendBuffer, readBuffer); TestUtility.Log($"Sending {sendBuffer.Length} bytes from listener->client"); sendTask = listenerStream.WriteAsync(sendBuffer, 0, sendBuffer.Length); readTask = this.ReadCountBytesAsync(clientStream, readBuffer, 0, readBuffer.Length, TimeSpan.FromSeconds(30)); await Task.WhenAll(sendTask, readTask); TestUtility.Log($"Sending and Reading complete"); Assert.Equal(sendBuffer, readBuffer); TestUtility.Log("Calling clientStream.Shutdown"); clientStream.Shutdown(); int bytesRead = await this.SafeReadAsync(listenerStream, readBuffer, 0, readBuffer.Length); TestUtility.Log($"listenerStream.Read returned {bytesRead} bytes"); Assert.Equal(0, bytesRead); TestUtility.Log("Calling listenerStream.Dispose"); listenerStream.Dispose(); TestUtility.Log("Calling clientStream.Dispose"); clientStream.Dispose(); } finally { await this.SafeCloseAsync(listener); } }
async Task ClientShutdownTest(EndpointTestType endpointTestType) { HybridConnectionListener listener = null; try { listener = GetHybridConnectionListener(endpointTestType); var client = GetHybridConnectionClient(endpointTestType); TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(30)); var clientStream = await client.CreateConnectionAsync(); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log("Client and Listener HybridStreams are connected!"); byte[] sendBuffer = this.CreateBuffer(1024, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); await clientStream.WriteAsync(sendBuffer, 0, sendBuffer.Length); TestUtility.Log($"clientStream wrote {sendBuffer.Length} bytes"); byte[] readBuffer = new byte[sendBuffer.Length]; await this.ReadCountBytesAsync(listenerStream, readBuffer, 0, readBuffer.Length, TimeSpan.FromSeconds(30)); Assert.Equal(sendBuffer, readBuffer); TestUtility.Log("Calling clientStream.Shutdown"); clientStream.Shutdown(); int bytesRead = await this.SafeReadAsync(listenerStream, readBuffer, 0, readBuffer.Length); TestUtility.Log($"listenerStream.Read returned {bytesRead} bytes"); Assert.Equal(0, bytesRead); TestUtility.Log("Calling listenerStream.Shutdown and Dispose"); listenerStream.Shutdown(); listenerStream.Dispose(); bytesRead = await this.SafeReadAsync(clientStream, readBuffer, 0, readBuffer.Length); TestUtility.Log($"clientStream.Read returned {bytesRead} bytes"); Assert.Equal(0, bytesRead); TestUtility.Log("Calling clientStream.Dispose"); clientStream.Dispose(); TestUtility.Log($"Closing {listener}"); await listener.CloseAsync(TimeSpan.FromSeconds(10)); listener = null; } finally { await this.SafeCloseAsync(listener); } }
async Task HybridConnectionTest(EndpointTestType endpointTestType, bool useBuiltInClientWebSocket) { HybridConnectionListener listener = null; try { listener = this.GetHybridConnectionListener(endpointTestType); listener.UseBuiltInClientWebSocket = useBuiltInClientWebSocket; var client = GetHybridConnectionClient(endpointTestType); client.UseBuiltInClientWebSocket = useBuiltInClientWebSocket; TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(30)); var clientStream = await client.CreateConnectionAsync(); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log("Client and Listener HybridStreams are connected!"); byte[] sendBuffer = this.CreateBuffer(1024, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); await clientStream.WriteAsync(sendBuffer, 0, sendBuffer.Length); TestUtility.Log($"clientStream wrote {sendBuffer.Length} bytes"); byte[] readBuffer = new byte[sendBuffer.Length]; await this.ReadCountBytesAsync(listenerStream, readBuffer, 0, readBuffer.Length, TimeSpan.FromSeconds(30)); Assert.Equal(sendBuffer, readBuffer); TestUtility.Log("Calling clientStream.CloseAsync"); var clientStreamCloseTask = clientStream.CloseAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token); TestUtility.Log("Reading from listenerStream"); int bytesRead = await this.SafeReadAsync(listenerStream, readBuffer, 0, readBuffer.Length); TestUtility.Log($"listenerStream.Read returned {bytesRead} bytes"); Assert.Equal(0, bytesRead); TestUtility.Log("Calling listenerStream.CloseAsync"); var listenerStreamCloseTask = listenerStream.CloseAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token); await listenerStreamCloseTask; TestUtility.Log("Calling listenerStream.CloseAsync completed"); await clientStreamCloseTask; TestUtility.Log("Calling clientStream.CloseAsync completed"); TestUtility.Log($"Closing {listener}"); await listener.CloseAsync(TimeSpan.FromSeconds(10)); listener = null; } finally { await this.SafeCloseAsync(listener); } }
private static async Task RunAsync() { var cts = new CancellationTokenSource(); // var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, myKey); // var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, myKey); var listener = new HybridConnectionListener(new Uri(String.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider); // Subscribe to the status events Console.BackgroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Black; listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); }; listener.Offline += (o, e) => { Console.WriteLine("Offline"); }; listener.Online += (o, e) => { Console.WriteLine("Online"); }; // Opening the listener will establish the control channel to // the Azure Relay service. The control channel will be continuously // maintained and reestablished when connectivity is disrupted. await listener.OpenAsync(cts.Token); Console.BackgroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Black; Console.WriteLine("Server " + RelayNamespace + " is listening..."); Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; // Providing callback for cancellation token that will close the listener. cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); // Start a new thread that will continuously read the console. new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start(); // Accept the next available, pending connection request. // Shutting down the listener will allow a clean exit with // this method returning null while (true) { var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } ProcessMessagesOnConnection(relayConnection, cts); } // Close the listener after we exit the processing loop await listener.CloseAsync(cts.Token); }
private async Task Listen(HybridConnectionListener listener, CancellationTokenSource cts) { // Accept the next available, pending connection request HybridConnectionStream relayConnection; do { relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection != null) { ProcessMessage(relayConnection, cts); } } while (relayConnection != null); }
private async Task StartInternalAsync(CancellationToken token) { while (!token.IsCancellationRequested) { var relayConnection = await _listener.AcceptConnectionAsync().ConfigureAwait(false); if (relayConnection == null) { continue; } ProcessMessagesOnConnection(relayConnection, token); //Task.Factory.StartNew(() => ProcessMessagesOnConnection(relayConnection, token), token, TaskCreationOptions.LongRunning, TaskScheduler.Current).GetAwaiter(); } }
/// <summary> /// Call HybridConnectionListener.AcceptConnectionAsync, once/if a listener is accepted /// read from its stream and echo the bytes until a 0-byte read occurs, then close. /// </summary> protected async void AcceptEchoListener(HybridConnectionListener listener) { try { var listenerStream = await listener.AcceptConnectionAsync(); if (listenerStream != null) { byte[] buffer = new byte[4 * 1024]; do { int bytesRead; try { bytesRead = await listenerStream.ReadAsync(buffer, 0, buffer.Length); } catch (Exception readException) { TestUtility.Log($"AcceptEchoListener {readException.GetType().Name}: {readException.Message}"); using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))) { await listenerStream.CloseAsync(cts.Token); } return; } using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))) { if (bytesRead == 0) { await listenerStream.CloseAsync(cts.Token); return; } else { await listenerStream.WriteAsync(buffer, 0, bytesRead, cts.Token); } } }while (true); } } catch (Exception e) { TestUtility.Log($"AcceptEchoListener {e.GetType().Name}: {e.Message}"); } }
async Task AcceptAsync(CancellationToken t) { logger.Site().Information("Accepting connections on {0}", ListenEndpoint); while (!t.IsCancellationRequested) { HybridConnectionStream connectionStream = null; try { connectionStream = await listener.AcceptConnectionAsync(); logger.Site().Debug("Accepted connection from {0}.", listener.Address); var connection = RelayEpoxyConnection.MakeServerConnection( parentTransport, this, serviceHost, connectionStream, logger, metrics); lock (connectionsLock) { connections.Add(connection); } await connection.StartAsync(); logger.Site().Debug("Started server-side connection for {0}", connection); } catch (AuthenticationException ex) { logger.Site().Error(ex, "Failed to authenticate remote connection from {0}", connectionStream); ShutdownSocketSafe(connectionStream); } catch (SocketException ex) { logger.Site().Error(ex, "Accept failed with error {0}.", ex.SocketErrorCode); ShutdownSocketSafe(connectionStream); } catch (ObjectDisposedException) { ShutdownSocketSafe(connectionStream); } } logger.Site().Information("Shutting down connection on {0}", ListenEndpoint); }
private async Task RunAsync() { _cts = new CancellationTokenSource(); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(_conn.SharedAccessKeyName, _conn.SharedAccessKey); var listener = new HybridConnectionListener(_conn.Endpoint, tokenProvider); // Subscribe to the status events listener.Connecting += Listener_Connecting; listener.Offline += Listener_Offline; listener.Online += Listener_Online; // Opening the listener will establish the control channel to // the Azure Relay service. The control channel will be continuously // maintained and reestablished when connectivity is disrupted. await listener.OpenAsync(_cts.Token); Console.WriteLine("Server listening"); // Providing callback for cancellation token that will close the listener. _cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); // Start a new thread that will continuously read the console. new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { _cts.Cancel(); })).Start(); // Accept the next available, pending connection request. // Shutting down the listener will allow a clean exit with // this method returning null while (true) { var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } ProcessMessagesOnConnection(relayConnection, _cts); } // Close the listener after we exit the processing loop await listener.CloseAsync(_cts.Token); }
private static async Task RunAsync() { var cts = new CancellationTokenSource(); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key); var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider); // Subscribe to the status events. listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); }; listener.Offline += (o, e) => { Console.WriteLine("Offline"); }; listener.Online += (o, e) => { Console.WriteLine("Online"); }; // Opening the listener establishes the control channel to // the Azure Relay service. The control channel is continuously // maintained, and is reestablished when connectivity is disrupted. await listener.OpenAsync(cts.Token); Console.WriteLine("Listener is setup and ready for messages"); // Provide callback for a cancellation token that will close the listener. cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); // Start a new thread that will continuously read the console. // If anything is entered on console. it will shutdown this application new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start(); // Accept the next available, pending connection request. // Shutting down the listener allows a clean exit. // This method returns null. while (true) { var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } ProcessMessagesOnConnection(relayConnection, cts); } // Close the listener after you exit the processing loop. await listener.CloseAsync(cts.Token); }
async Task AcceptLoopAsync() { while (!shuttingDown.IsCancellationRequested) { try { var hybridConnectionStream = await listener.AcceptConnectionAsync(); if (hybridConnectionStream == null) { // we only get null if trhe listener is shutting down break; } HandleRelayConnectionAsync(hybridConnectionStream).Fork(this); } catch (Exception e) { BridgeEventSource.Log.HandledExceptionAsWarning(activity, e); } } }
static void Main(string[] args) { HybridConnectionListener listener = new HybridConnectionListener("Endpoint=sb://relayzs.servicebus.windows.net/;SharedAccessKeyName=sas;SharedAccessKey=WBhKG1Fb51sYz4I1Nsv/mZsLhnru+O08YQxeq+SyRfo=;EntityPath=hybirdconn1"); listener.OpenAsync(); Task <HybridConnectionStream> task = listener.AcceptConnectionAsync(); while (!task.IsCompleted) { } HybridConnectionStream stream = task.Result; StreamReader reader = new StreamReader(stream); StreamWriter writer = new StreamWriter(stream); String message = reader.ReadLine(); Console.WriteLine(message); writer.WriteLine("Hello Client!"); writer.Flush(); reader.Close(); writer.Close(); }
public async Task Start() { try { await _hybridConnectionListener.OpenAsync(_cts.Token); } catch (Exception e) { _logger.LogError(e, $"Unable to open hybrid connection listener for {_relayNamespace}/{_connectionName}"); return; } await Task.Factory.StartNew(async() => { _cts.Token.Register(() => _hybridConnectionListener.CloseAsync(CancellationToken.None)); while (true) { var client = await _hybridConnectionListener.AcceptConnectionAsync(); if (null == client) { await _hybridConnectionListener.CloseAsync(CancellationToken.None); return; } var streamId = Guid.NewGuid(); lock (_syncRoot) { _hybridConnectionStreams.Add(streamId, client); } await OnNewClient(streamId, client, _cts.Token); } }); }
async Task ListenerAbortWhileClientReadingTest(EndpointTestType endpointTestType) { HybridConnectionListener listener = null; try { listener = GetHybridConnectionListener(endpointTestType); var client = GetHybridConnectionClient(endpointTestType); TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(30)); var clientStream = await client.CreateConnectionAsync(); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log("Client and Listener HybridStreams are connected!"); using (var cancelSource = new CancellationTokenSource()) { TestUtility.Log("Aborting listener WebSocket"); cancelSource.Cancel(); await listenerStream.CloseAsync(cancelSource.Token); } byte[] readBuffer = new byte[1024]; await Assert.ThrowsAsync <RelayException>(() => clientStream.ReadAsync(readBuffer, 0, readBuffer.Length)); TestUtility.Log("Calling clientStream.Close"); var clientCloseTask = clientStream.CloseAsync(CancellationToken.None); } finally { await this.SafeCloseAsync(listener); } }
static async void RunAcceptPump(HybridConnectionListener listener) { while (true) { try { HybridConnectionStream stream = await listener.AcceptConnectionAsync(); if (stream == null) { return; } string connectionName = $"L:HybridConnectionStream({stream.TrackingContext.TrackingId})"; RelayTraceSource.TraceInfo($"{connectionName} accepted"); RunConnectionPump(stream, connectionName, echoBytes: true); } catch (Exception exception) { RelayTraceSource.TraceException(exception, nameof(RunAcceptPump)); await Task.Delay(TimeSpan.FromMilliseconds(100)); } } }
static async Task Main(string[] args) { string hostAddress; string hybridConnectionName; string clientId = null; string tenantId = null; string clientSecret = null; RbacAuthenticationOption option; if (args.Length == 2) { option = RbacAuthenticationOption.ManagedIdentity; hostAddress = args[0]; hybridConnectionName = args[1]; } else if (args.Length == 3) { option = RbacAuthenticationOption.UserAssignedIdentity; hostAddress = args[0]; hybridConnectionName = args[1]; clientId = args[2]; } else if (args.Length == 5) { option = RbacAuthenticationOption.AAD; hostAddress = args[0]; hybridConnectionName = args[1]; clientId = args[2]; tenantId = args[3]; clientSecret = args[4]; } else { Console.WriteLine("Please run with parameters of the following format for the corresponding RBAC authentication method:"); Console.WriteLine("System Managed Identity: [HostAddress] [HybridConnectionName]"); Console.WriteLine("User Assigned Identity: [HostAddress] [HybridConnectionName] [ClientId]"); Console.WriteLine("Azure Active Directory: [HostAddress] [HybridConnectionName] [ClientId] [TenantId] [ClientSecret]"); Console.WriteLine("Press <Enter> to exit..."); Console.ReadLine(); return; } TokenProvider tokenProvider = null; switch (option) { case RbacAuthenticationOption.ManagedIdentity: tokenProvider = TokenProvider.CreateManagedIdentityTokenProvider(); break; case RbacAuthenticationOption.UserAssignedIdentity: var managedCredential = new ManagedIdentityCredential(clientId); tokenProvider = TokenProvider.CreateManagedIdentityTokenProvider(managedCredential); break; case RbacAuthenticationOption.AAD: tokenProvider = GetAadTokenProvider(clientId, tenantId, clientSecret); break; } var hybridConnectionUri = new Uri($"{hostAddress}/{hybridConnectionName}"); HybridConnectionListener listener = null; try { // The HybridConnection should be already created through Azure Portal or other means Console.WriteLine($"Creating the Relay listener instance with RBAC option: {option}"); listener = new HybridConnectionListener(hybridConnectionUri, tokenProvider); await listener.OpenAsync(TimeSpan.FromSeconds(10)); Console.WriteLine("Created and connected the Relay listener instance."); Console.WriteLine($"Creating the Relay sender instance with RBAC option: {option}"); var sender = new HybridConnectionClient(hybridConnectionUri, tokenProvider); var createSenderTask = sender.CreateConnectionAsync(); var listenerAcceptTask = listener.AcceptConnectionAsync(); using (HybridConnectionStream senderStream = await createSenderTask) using (HybridConnectionStream listenerStream = await listenerAcceptTask) { Console.WriteLine("Created and connected the Relay sender instance."); var senderCloseTask = senderStream.CloseAsync(CancellationToken.None); await listenerStream.CloseAsync(CancellationToken.None); await senderCloseTask; } // Configure a RequestHandler for HTTP request/response mode listener.RequestHandler = (context) => { context.Response.StatusCode = HttpStatusCode.OK; using (var sw = new StreamWriter(context.Response.OutputStream)) { sw.WriteLine("hello!"); } // The context must be closed to complete sending the response context.Response.Close(); }; Console.WriteLine($"Sending a HTTP request by setting the token in request header with RBAC option: {option}"); SecurityToken token = await tokenProvider.GetTokenAsync(hybridConnectionUri.AbsoluteUri, TimeSpan.FromMinutes(30)); var request = new HttpRequestMessage(); request.Headers.Add(HttpRequestHeader.Authorization.ToString(), token.TokenString); var requestUri = new UriBuilder(hybridConnectionUri) { Scheme = "https" }.Uri; using (HttpClient client = new HttpClient { BaseAddress = requestUri }) { using (var response = await client.SendAsync(request)) { Console.WriteLine($"Response status code: {response.StatusCode}. Response reason phrase: {response.ReasonPhrase}"); } } Console.WriteLine($"Sending a HTTP request by setting the token in query string with RBAC option: {option}"); token = await tokenProvider.GetTokenAsync(hybridConnectionUri.AbsoluteUri, TimeSpan.FromMinutes(30)); request = new HttpRequestMessage(); requestUri = new UriBuilder(requestUri) { Query = $"?sb-hc-token={token.TokenString}" }.Uri; using (HttpClient client = new HttpClient { BaseAddress = requestUri }) { using (var response = await client.SendAsync(request)) { Console.WriteLine($"Response status code: {response.StatusCode}. Response reason phrase: {response.ReasonPhrase}"); } } Console.WriteLine("Press <Enter> to exit..."); Console.ReadLine(); } finally { if (listener != null) { await listener.CloseAsync(); } } }
async Task RequestHeadersTest(EndpointTestType endpointTestType) { HybridConnectionListener listener = null; try { listener = this.GetHybridConnectionListener(endpointTestType); var client = GetHybridConnectionClient(endpointTestType); var listenerRequestTcs = new TaskCompletionSource <IDictionary <string, string> >(); listener.AcceptHandler = (context) => { try { var headers = new Dictionary <string, string>(); foreach (string headerName in context.Request.Headers.AllKeys) { headers[headerName] = context.Request.Headers[headerName]; } listenerRequestTcs.SetResult(headers); return(Task.FromResult(true)); } catch (Exception e) { listenerRequestTcs.TrySetException(e); throw; } }; TestUtility.Log($"Opening {listener}"); await listener.OpenAsync(TimeSpan.FromSeconds(30)); const string ExpectedRequestHeaderName = "CustomHeader1"; const string ExpectedRequestHeaderValue = "Some value here; other-value/here."; var clientRequestHeaders = new Dictionary <string, string>(); clientRequestHeaders[ExpectedRequestHeaderName] = ExpectedRequestHeaderValue; var clientStream = await client.CreateConnectionAsync(clientRequestHeaders); var listenerStream = await listener.AcceptConnectionAsync(); TestUtility.Log("Client and Listener HybridStreams are connected!"); Assert.True(listenerRequestTcs.Task.Wait(TimeSpan.FromSeconds(5)), "AcceptHandler should have been invoked by now."); IDictionary <string, string> listenerRequestHeaders = await listenerRequestTcs.Task; Assert.True(listenerRequestHeaders.ContainsKey(ExpectedRequestHeaderName), "Expected header name should be present."); Assert.Equal(ExpectedRequestHeaderValue, listenerRequestHeaders[ExpectedRequestHeaderName]); byte[] sendBuffer = this.CreateBuffer(1025, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); await clientStream.WriteAsync(sendBuffer, 0, sendBuffer.Length); TestUtility.Log($"clientStream wrote {sendBuffer.Length} bytes"); byte[] readBuffer = new byte[sendBuffer.Length]; await this.ReadCountBytesAsync(listenerStream, readBuffer, 0, sendBuffer.Length, TimeSpan.FromSeconds(30)); Assert.Equal(sendBuffer, readBuffer); var clientStreamCloseTask = clientStream.CloseAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token); await listenerStream.CloseAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token); await clientStreamCloseTask; TestUtility.Log($"Closing {listener}"); await listener.CloseAsync(TimeSpan.FromSeconds(10)); listener = null; } finally { await this.SafeCloseAsync(listener); } }
protected override TTransport AcceptImpl() { var acceptedConnection = listener.AcceptConnectionAsync().GetAwaiter().GetResult(); return(new TStreamTransport(acceptedConnection, acceptedConnection)); }
RelayListenerInitializeAsync( string relayNamespace, string connectionName, string keyName, string key, TimeSpan?timeout = null, CancellationTokenSource cancellationTokenSource = null) { if (_isInitialized) { throw new RelayListenerException("Relay Listener can only be initialized once. Create a new instance if multiple listeners are needed."); } _isInitialized = true; // Set default timout to 10 seconds. var to = timeout ?? TimeSpan.FromSeconds(10); var cts = cancellationTokenSource ?? new CancellationTokenSource(); var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(keyName, key); var listener = new HybridConnectionListener(new Uri($"sb://{relayNamespace}/{connectionName}"), tokenProvider); // Subscribe to the connection status events. listener.Connecting += ConnectingHandler; listener.Offline += OfflineHandler; listener.Online += OnlineHandler; await listener.OpenAsync(cts.Token); _relayStateObserver.OnNext(RelayListenerConnectionState.Listening); var observableRelayMessages = Observable.Create <IMessage>(obs => { IDisposable disposableRelayMessages = null; var disposableConnections = Observable.While( () => !cts.IsCancellationRequested, Observable.FromAsync(() => listener.AcceptConnectionAsync())) .Subscribe(connection => { if (connection != null) { disposableRelayMessages = _observableRelayStringLine(connection, cts.Token, to) .Subscribe(obs.OnNext, obs.OnError); } }, ex => { _relayStateObserver.OnError(ex); obs.OnError(ex); }, () => { _relayStateObserver.OnCompleted(); obs.OnCompleted(); }); return(Disposable.Create(() => { disposableConnections?.Dispose(); disposableRelayMessages?.Dispose(); _relayStateObserver.OnNext(RelayListenerConnectionState.ExitingListener); try { listener.CloseAsync(CancellationToken.None).Wait(new CancellationTokenSource(to).Token); } catch (Exception ex) { _relayStateObserver.OnError(ex); } finally { cts?.Dispose(); } listener.Connecting -= ConnectingHandler; listener.Offline -= OfflineHandler; listener.Online -= OnlineHandler; _relayStateObserver.OnCompleted(); })); }).Publish().RefCount(); return(_relayStateObservable, observableRelayMessages); }
static async Task RunAsync(string[] args) { var cts = new CancellationTokenSource(); if (args.Length < 4) { Console.WriteLine("server [ns] [hc] [keyname] [key]"); return; } var ns = args[0]; var hc = args[1]; var keyname = args[2]; var key = args[3]; // Create a new hybrid connection listener to listen for // incoming connections. var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(keyname, key); var listener = new HybridConnectionListener(new Uri(String.Format("sb://{0}/{1}", ns, hc)), tokenProvider); // Subscribe to the status events listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); }; listener.Offline += (o, e) => { Console.WriteLine("Offline"); }; listener.Online += (o, e) => { Console.WriteLine("Online"); }; // Opening the listener will establish the control channel to // the Azure Relay service. The control channel will be continuously // maintained and reestablished when connectivity is disrupted. await listener.OpenAsync(cts.Token); Console.WriteLine("Server listening"); // trigger cancellation when the user presses enter. Not awaited. #pragma warning disable CS4014 cts.Token.Register(() => listener.CloseAsync(CancellationToken.None)); Task.Run(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })); #pragma warning restore CS4014 do { // Accept the next available, pending connection request. // Shutting down the listener will allow a clean exit with // this method returning null var relayConnection = await listener.AcceptConnectionAsync(); if (relayConnection == null) { break; } // The following task processes a new session. We turn off the // warning here since we intentially don't 'await' // this call, but rather let the task handdling the connection // run out on its own without holding for it #pragma warning disable CS4014 Task.Run(async() => { Console.WriteLine("New session"); // The connection is a fully bidrectional stream. // We put a stream reader and a stream writer over it // that allows us to read UTF-8 text data that comes from // the sender and to write text replies back. var reader = new StreamReader(relayConnection); var writer = new StreamWriter(relayConnection) { AutoFlush = true }; do { // Read a line of input until a newline is encountered string line = await reader.ReadLineAsync(); if (String.IsNullOrEmpty(line)) { // If there's no input data, we will signal that // we will no longer send data on this connection // and then break out of the processing loop. await relayConnection.ShutdownAsync(cts.Token); break; } // Output the line on the console Console.WriteLine(line); // Write the line back to the client, prepending "Echo:" await writer.WriteLineAsync("Echo: " + line); }while (!cts.IsCancellationRequested); Console.WriteLine("End session"); // closing the connection from this end await relayConnection.CloseAsync(cts.Token); }); #pragma warning restore CS4014 }while (true); // close the listener after we exit the processing loop await listener.CloseAsync(cts.Token); }