Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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;
            }
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        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);
            }
        }
Exemple #8
0
        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);
            }
        }
Exemple #10
0
        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);
        }
Exemple #12
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #17
0
        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);
                }
            }
        }
Exemple #18
0
        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);
                }
            });
        }
Exemple #20
0
        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));
                }
            }
        }
Exemple #22
0
        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);
            }
        }
Exemple #24
0
        protected override TTransport AcceptImpl()
        {
            var acceptedConnection = listener.AcceptConnectionAsync().GetAwaiter().GetResult();

            return(new TStreamTransport(acceptedConnection, acceptedConnection));
        }
Exemple #25
0
        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);
        }