How to build Azure Service Bus Relay Sender and Listener?

This is one of them, I tried to do and found it hard so here is how I did it, post. I was assigned to look into how to build a Sender and Listener using the Azure Service Bus Relay, so we could send data from Azure to On Premise securely. Now there might be debates on is this is secure and compared to other methods, but that is not for what I was asked and what this post is about.

Therefore I will demo how to create the Net TCP Relay in Azure, the code to a listener and the code for the sender in C#.net, but remember this is what worked for me and there are other protocols, technologies and languages this can be done in.

How to build the Service Bus Relay

First you need to get to the Azure Portal using ‘https://portal.azure.com‘. This will take you to the dashboard or to the login page, which will then take you there. You can create a new dashboard to put all your resources in one place, which is advised for organisation.

Click on the ‘New’ button in the side navigation, then search for ‘Relay’. This should then show in the results the Relay service with the blue icon. Click ‘Create’ on this and you will be promoted for the details of the relay.

v1

Add in the Azure name for the relay, this is the base URL for the service. Select your preferred Subscription, Resource group and Location as you see fit. Once the details are in and the fields have a green tick in for being ok, then press the ‘Create’ button. If you want this pinned on your dashboard, then don’t forget to check the ‘Pin to dashboard’ box.

v2

Once this is created then you can go to the Relay and you will see the Overview page of the new Relay as below.

v3

Now the method that I create this was using the ‘WCF Relay’ and it was a ‘NetTcp’ version. To do this click on the ‘WCF Relay’ menu in the side navigation below the ‘Overview’ item. This will load the list view of all the WCF Relays you have, which is none yet. Click on the ‘WCF Relay’ button at the top with the big plus symbol next to it.

Enter the name of the Relay, remember that you can have many of these so it doesn’t have to be to generic. The other details I left as they were and you will notice that ‘NetTcp’ is selected for ‘Relay Type’. Click ‘Create’ and now you have a Relay.

v4

Note that if you can’t see the Relay after pressing the button, then reload the screen and it will load in this time.

v5

Now you can move on to the code.

 

How to build a Relay Sender in C#.Net

A key part to the two code segments working together is that the interface they both use must match or the data will not get received or sent.

We start by creating the 3 variables that are needed for each Relay account. This is the Service Bus Key, the Namespace and the Relay name.

To get the Service Bus Key, go to the Relay account page and under ‘Properties’ on the side navigation there should be ‘Shared access policies’, click on this. You will know if you are on the correct page as there will already be a ‘RootManageShareAccessKey’, which new keys can be made to separate security, but for this POC I just used this one.
If you click on this you will see the keys associated with the policy. You need the ‘Primary key’, which you can copy and put into the variable below:

private string _serviceBusKey = "[RootManageShareAccessKey-PrimaryKey]";

The other two you can get from the WCF Relay Overview page. The Namespace is the name of the Relay Account and the Relay name is what the WCF Relay is called. These can also be taken from the ‘WCF Relay Url’ on the overview page.

http:// [NAMESPACE] .servicebus.windows.net/ [WCF RELAY NAME]

private string _namespace = "[Namespace]";
private string _relayName = "[WcfRelayName]";

Next we create the variable for the connection to the Relay, by creating a new Net TCP binding and the Endpoint. The scheme I used was ‘sb’ but this again can be changed.

var binding = new NetTcpRelayBinding();
var endpoint =
new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", _namespace, _relayName));

Visual Studio should help you import the correct variable, but if not then you need the following
• NetTcpRelayBinding
• Microsoft.Servicebus
• EndpointAddress

Now we connect these to the interface that is the same as the Listener and create the tunnel between them.

// Factory
var factory = new ChannelFactory<IMyService>(binding, endpoint);
factory.Endpoint.Behaviors.Add(
new TransportClientEndpointBehavior
{
TokenProvider =
TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey",
_serviceBusKey)
}
);

IMyService client = factory.CreateChannel();

From now on when you want to call a method to the listener, you use ‘client’ dot, the method or variable, for example.

client.CallMyService();

How to build a Relay Listener in C#.Net

Now to get this side working is very simple as it is all managed from the Web Configuration file (Web.config).

Step 1 is under the ‘Configuration > system.seriveModel > behaviors > endpointBehavoirs’
In this node add a new behavior called ‘ServiceBusBehavior’ and inside this you need a ‘transportClientEndpointBehavior’ with a sub node of a ‘tokenProvider’. In this you will have the ‘sharedAccessSignature’ which is the ‘RootManageSahredAccessKey’ mentioned before.

You can get this from the Service Bus Key, go to the Relay account page and under ‘Properties’ on the side navigation there should be ‘Shared access policies’, click on this. You will know if you are on the correct page as there will already be a ‘RootManageShareAccessKey’, which new keys can be made to separate security, but for this POC I just used this one.
If you click on this you will see the keys associated with the policy. You need the ‘Primary key’, which you can copy and put into the variable below:

<endpointBehaviors>
<behavior name="ServiceBusBehavior">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedAccessSignature keyName="RootManageSharedAccessKey" key="PRIMARY KEY"/>
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>

Step 2 is to create the new binding for the Net TCP connection under ‘Configuration > system.seriveModel > bindings’. Add in this a ‘netTcpRelayBinding’ node, with a ‘binding’ node. The name of this will be called ‘ServiceBinding’, but can be custom if you would like.

<bindings>
<basicHttpBinding>
<binding name="DefaultBinding" />
</basicHttpBinding>
<netTcpRelayBinding>
<binding name="ServiceBusBinding" />
</netTcpRelayBinding>
</bindings>

Step 3 is the connection settings for the Service Bus. Again you will need the ‘RootManageSahredAccessKey’ and also the Relay Namespace or the URL. The below sits under ‘Configuration > appSettings’, replacing the items in [] with the correct values.

<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString"
value="Endpoint=sb://[Namespace].servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[PrimaryKey]"/>
</appSettings>

Step 4 is the last on, ish. This is to bind the service to all the configurations we just made. To complete this step you would have needed to create the WCF service and the above bindings. Under the ‘Configuration > system.seriveModel > services’ add a new service node as below:

<service name="[WCF_Service]">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="DefaultBinding" contract="[WCF_Interface]"/>
<endpoint address="sb://[Namespace].servicebus.windows.net/[WCF_Relay]" binding="netTcpRelayBinding" behaviorConfiguration="ServiceBusBehavior"
contract="[WCF_Interface]" />
</service>

Replace the above variables as below:
• [WCF_Service] = the WCF service class
• [WCF_Interface] = the WCF service Interface
• [Namespace] = the Relay name
• [WCF_Relay] = the WCF Relay name

This one is an optional step, or more of a put it in if you want all the functionality. I would advise unless you know what you are playing with, then don’t touch it. In the ‘Configuration > system.seriveModel > extensions’ node you need to add the below, which are all the service bus extensions.

<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior"
type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="serviceRegistrySettings"
type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="tcpRelayTransport"
type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="httpRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="httpsRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="onewayRelayTransport"
type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="webHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ws2007HttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netOnewayRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netEventRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="netMessagingBinding"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>

Side Note

To pass custom classes between the two you need to decorate the class with the data attributes, but also make sure you have a unique namespace on the contract. It doesn’t have to be a valid running namespace, just as long as they match and are unique.

[DataContract(Name= "CarClass",Namespace = "http://MyDomain.com/namespace/CarClass")]
public class CarClass
{
[DataMember]
public string CarName { get; set; }
[DataMember]
public string CarType { get; set; }
[DataMember]
public string CarSize { get; set; }
}

 

How to test a WCF service with Visual Studio Command Prompt?

It can be a pain sometime to test your web service and a longer process than wanted. I then found a method from the glorious web of how to use Visual Studio to test and thought I would share this with you.

To test we are going to use the WCF Test Client from Visual Studio 2010. You can find this by either going to the programs folder, which is located at ‘Start > All Programs > Microsoft Visual Studio 2010 > Visual Studio Tools > Visual Studio Command Prompt (2010)‘. The other way would to be search for ‘visual studio command prompt’ in the start menu like below.

w1

 1) Once it is loaded you should get the command prompt showing like below:

w2

2) Type in the following command ‘wcftestclient‘ and click enter.

w3

3) You should then be presented with the WCF Test Client window like this:

w4

4) To add a new service, click the ‘File’ button from the menu, then ‘Add Service…’

w5

5) You will now be prompted with another window to enter the endpoint of your service. This can be a full domain or even a local one as long as it has a WSDL.

w6

6) Once your service is added, you will see the public methods with the pink box next to them and there is also the configuration file called ‘Config File’. If you double click on the public method you will be presented with the Request and Response sections.

w7

The Request section shows all the parameters, that the method accepts including the Type as well. Enter in the correct values and then press ‘Invoke’ to trigger the service.

You should now have a response back in the Response section.

How to get the users IP Address in C#.NET?

When you search this on your favourite search engine, (Google) you will get flooded by load of different way to get the end result. This is great in a sense as you know there are thousands of people with different answers, but then that is where the problem is at. There are so many single responses to how you can get the users IP Address in C#.NET, but not one that shows you everything. Therefore I will present to you below different methods to get the users IP and how I have implemented it in a project.

All the methods I found to be best are using the Request Server Variables. These are predetermined environment variables and request header information. This is why you can get IP address as it is part of the header information.

The standard server variable to use is ‘REMOTE_ADDR’, which is done as the following:

HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

However if the user is behind a proxy server, then the above will return that IP Address and not the actual users. The server variable to get the users IP address from behind the proxy server is ‘HTTP_X_FORWARDED_FOR’ done as below:

HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

Then you get that issue of not knowing if the user is behind a proxy or not, as the first example will return one or the other and the second example will only return a value if there is a proxy server. Therefore we need to find out if there is a proxy server or not. You can do this with the server variable ‘HTTP_VIA’, if this has a value then they must be using a proxy server and so you can get the correct IP as below:

If (HttpContext.Current.Request.ServerVariables[“HTTP_VIA”] != null) {
return HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
}

return HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

Or another method is to do it in reverse and check if the proxy method is not null first instead like:

string userIp = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

if (string.IsNullOrEmpty(userIp)){
return HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}

return userIp;

This is the best method I found to get the users IP Address in ASP.NET C#, but if you think there is a better way then please comment below with your solution.