{"id":15291026,"url":"https://github.com/azure/azure-relay-dotnet","last_synced_at":"2025-04-12T04:53:23.479Z","repository":{"id":46553527,"uuid":"67644797","full_name":"Azure/azure-relay-dotnet","owner":"Azure","description":"☁️ .NET Standard client library for Azure Relay Hybrid Connections","archived":false,"fork":false,"pushed_at":"2024-10-23T15:47:28.000Z","size":729,"stargazers_count":37,"open_issues_count":29,"forks_count":35,"subscribers_count":23,"default_branch":"dev","last_synced_at":"2025-04-12T04:53:12.658Z","etag":null,"topics":["azure","https","hybrid-connections","relay","websocket"],"latest_commit_sha":null,"homepage":"https://docs.microsoft.com/en-us/azure/service-bus-relay/relay-what-is-it","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Azure.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-07T21:25:38.000Z","updated_at":"2025-03-19T11:57:29.000Z","dependencies_parsed_at":"2023-12-11T21:29:18.744Z","dependency_job_id":"9aed9700-9e6a-45f6-bb9c-693705800f5d","html_url":"https://github.com/Azure/azure-relay-dotnet","commit_stats":{"total_commits":134,"total_committers":16,"mean_commits":8.375,"dds":0.4701492537313433,"last_synced_commit":"f7726b855edb8d7eef7c0bec91223c2a7e4fbd6f"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-relay-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-relay-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-relay-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-relay-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Azure","download_url":"https://codeload.github.com/Azure/azure-relay-dotnet/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248519472,"owners_count":21117757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","https","hybrid-connections","relay","websocket"],"created_at":"2024-09-30T16:10:38.638Z","updated_at":"2025-04-12T04:53:23.460Z","avatar_url":"https://github.com/Azure.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿\u003cp align=\"center\"\u003e\n  \u003cimg src=\"relay.png\" alt=\"Microsoft Azure Relay\" width=\"100\"/\u003e\n\u003c/p\u003e\n\n# Microsoft Azure Relay Hybrid Connections Client for .NET\n\n|Build/Package|Status|\n|------|-------------|\n|master|[![Build status](https://ci.appveyor.com/api/projects/status/qhefoxrdg068xjhj/branch/master?svg=true)](https://ci.appveyor.com/project/jtaubensee/azure-relay-dotnet/branch/master) [![codecov](https://codecov.io/gh/Azure/azure-relay-dotnet/branch/master/graph/badge.svg)](https://codecov.io/gh/Azure/azure-relay-dotnet)|\n|dev|[![Build status](https://ci.appveyor.com/api/projects/status/qhefoxrdg068xjhj/branch/dev?svg=true)](https://ci.appveyor.com/project/jtaubensee/azure-relay-dotnet/branch/dev) [![codecov](https://codecov.io/gh/Azure/azure-relay-dotnet/branch/dev/graph/badge.svg)](https://codecov.io/gh/Azure/azure-relay-dotnet)|\n|Microsoft.Azure.Relay|[![NuGet Version and Downloads count](https://buildstats.info/nuget/Microsoft.Azure.Relay?includePreReleases=true)](https://www.nuget.org/packages/Microsoft.Azure.Relay/)|\n\nThis library is built using .NET Standard 2.0. For more information on what platforms are supported see [.NET Platforms Support](https://docs.microsoft.com/en-us/dotnet/articles/standard/library#net-platforms-support).\n\nAzure Relay is one of the key capability pillars of the Azure Service Bus\nplatform. The Relay’s new \"Hybrid Connections\" capability is a secure,\nopen-protocol evolution based on HTTP and WebSockets. It supersedes the former,\nequally named \"BizTalk Services\" feature that was built on a proprietary\nprotocol foundation. The integration of Hybrid Connections into Azure App\nServices will continue to function as-is.\n\n\"Hybrid Connections\" allows establishing bi-directional, binary stream\ncommunication between two networked applications, whereby either or both parties\ncan reside behind NATs or Firewalls. This document describes the client-side\ninteractions with the Hybrid Connections relay for connecting clients in\nlistener and sender roles and how listeners accept new connections.\n\nThis repository contains samples showing how to use the Hybrid Connections\ncapability from C# and it also holds the protocol documentation.\n\n## How to provide feedback\n\nSee our [Contribution Guidelines](./.github/CONTRIBUTING.md).\n\n## Samples\n\nFor Relay Hybrid Connections samples, see the [azure/azure-relay](https://github.com/Azure/azure-relay/tree/master/samples/hybrid-connections) service repository.\n\n## Using Hybrid Connections from C# \n\nThe API discussed here is implemented in the new Microsoft.Azure.Relay.dll\nassembly, which can be added to your .NET project via a NuGet package.\n\n### Registering Hybrid Connections \n\nTo use the Hybrid Connection feature, you must first register a Hybrid\nConnection path with the Relay service. Hybrid Connection paths are string\nexpressions that uniquely identify the entity. \n\nTo create Hybrid Connection entities, you first need a Service Bus Relay\nnamespace that you can create either through the Azure portal, the Azure\nPowerShell tools, or the cross-platform Azure CLI. \n\nExisting Azure Relay namespaces can be managed in the Azure Portal, where you\ncan also add, edit, or remove Hybrid Connection paths interactively. \n\nThe\nfollowing two settings are specific to Hybrid Connections: \n\n| Property                    | Description                          |\n|-----------------------------|--------------------------------------|\n| RequiresClientAuthorization | If this is set to false (the default is true), sending clients can connect to a listener through the Relay without providing an authorization token. In this case, the Relay will not enforce any if its ownaccess rules, but the listener can still evaluate the Authorization HTTP header or use some other model for access control. |\n| ListenerCount               | This is an informational value that’s available via GetRuntimeInformationAsync and gives the number of connected listeners on this Hybrid Connection as the value is queried. |\n\nUp to 25 listeners can be concurrently connected and the Relay will distribute\nincoming connection requests across all connected listeners, equivalent to a\nnetwork load balancer.\n\n### Handling Tokens\n\nCreating a listener requires an access token that confers the \"Listen\" right on\nthe Hybrid Connection entity or at the namespace level. Creating a sender\nconnection requires, unless the Hybrid Connection entity is configured\notherwise, a token that confers the \"Send\" right. The follows the [shared access\nsignature authentication\nmodel](https://azure.microsoft.com/documentation/articles/service-bus-shared-access-signature-authentication/)\nthat is common across all Service Bus capabilities and entities.\n\nAccess tokens are created from an Authorization rule and key using a token\nprovider helper as described in the article linked above; the Hybrid Connections\nAPI has its own ```TokenProvider``` class, however. The ```TokenProvider``` can\nbe initialized from a rule and key with\n```TokenProvider.CreateSharedAccessSignatureTokenProvider(ruleName, key)``` or\nit can be initialized from an existing token string that has been issued by some\nother application with ```TokenProvider.CreateSharedAccessSignatureTokenProvider(token)```.\n\nThe initialized ```TokenProvider``` instance is used by the ```HybridConnectionListener```\nand ```HybridConnectionClient``` API to create tokens as needed. \n\nHowever, with Hybrid Connections even more than with other Service Bus features,\nyou may have scenarios where you will want the Relay to protect your endpoint,\nbut you also don’t want to hand the SAS rule and key to the client outright. One\nsuch case are browser-based clients. For a browser-based client that needs to\nconnect to a resource made available via a relayed WebSocket, the server-side\nweb site can hold on to the required SAS rule and key, and use the ```TokenProvider```\nto create a short-lived token string and pass that on to the client: \n\n```csharp\nvar token = await TokenProvider.GetTokenAsync(\"http://namespace.servicebus.windows.net/path\", TimeSpan.FromSeconds(30));\nvar tokenString = token.TokenString;\n```\n\nThe token created in the exemplary snippet above will only be valid to establish\na connection within 30 seconds of receiving it.\n\n### Creating Listeners \n\nThe Hybrid Connection API follows a very common networking design pattern. There\nis a listener object that is first opened to allow incoming connections to flow\nand from which the application can then accept these incoming connections for\nhandling. \n\n```csharp\nvar listener = new HybridConnectionListener(\"sb://namespace.servicebus.windows.net/path\", tokenProvider); \nawait listener.OpenAsync(TimeSpan.FromSeconds(60)); \ndo \n{ \n    var connection = await listener.AcceptConnectionAsync(); \n    Task.Run(()=\u003ethis.HandleConnection(connection)); \n} \nwhile( … ); \n```\n\n\nThe connections are modeled as and based on .NET streams, with\nthe distinction that they have a ```Shutdown/Async()``` operation that cleanly signals\nto the connected party that this process is done sending data, and a\n```CloseAsync()``` operation to cleanly close the connection. \n\nBoth of these operations also echo common networking API patterns Since the base\nclass is ```System.IO.Stream```, the ```HybridConnectionStream``` can be used\nwith all .NET APIs that expect streams. This includes all standard stream\nreaders and writers and most common stream data encoders and decoders\n(serializers).\n\nThe ```HybridConnectionListener``` will\naggressively attempt to stay connected once opened. Should the local network\nconnection drop or connectivity to the Relay become interrupted, the listener\nwill patiently retry until the listener can be restored. \n\nListeners on clients that are location-agile and may change networks or be put\ninto sleep mode will also reconnect automatically as circumstances permit. The\napplication can observe the connection state through the ```Connecting```,\n```Online```, and ```Offline``` events that fire when the network status\nchanges. The ```IsOnline``` property reflects the current connection status, and\n```LastError``` provides insight into the reason why the last connection attempt\nfailed, if the listener transitions its state to ```Connecting``` or ```Offline```.\n\n### Creating Clients \n\nClient connections are created using the ```HybridConnectionClient``` class.\nThere are two variants of the constructor: one takes the target address and a\n```TokenProvider``` that can produce a \"Send\" token for the target; the other\nomits the token provider for use with Hybrid Connections that are set up without\nclient authorization.\n\nNew connections are created via the ```CreateConnectionAsync()``` method. When\nthe connection has been established, the method returns a\n```HybridConnectionStream``` that is connected to the remote listener. If the\nconnection attempt fails, a ```RelayException``` will be raised that indicates the\nreason for why the connection could not be established.\n\n## How do I run the unit tests? \n\nIn order to run the unit tests, you will need to do the following:\n\n1. Deploy the Azure Resource Manager template located at [/build/azuredeploy.json](./build/azuredeploy.json) by clicking the following button:\n\n    \u003ca href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-service-bus-dotnet%2Fmaster%2Fbuild%2Fazuredeploy.json\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://azuredeploy.net/deploybutton.png\"/\u003e\n    \u003c/a\u003e\n\n    *Running the above template will provision a namespace along with the required entities to successfully run the unit tests.*\n    *Alternatively, you can create your own Relay namespace and the following Hybrid Connection entities in it: Authorized and Unauthorized. Toggle client authorization as appropriate for each one.*\n\n1. Add an Environment Variable named `azure-relay-dotnet/connectionstring` and set the value as the connection string of the newly created namespace. **Please note that if you are using Visual Studio, you must restart Visual Studio in order to use new Environment Variables.**\n\nOnce you have completed the above, you can run `dotnet test` from the `/test/Microsoft.Azure.Relay.UnitTests` directory.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazure%2Fazure-relay-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazure%2Fazure-relay-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazure%2Fazure-relay-dotnet/lists"}