2012年10月1日

[Azure]Invoking WCF Service hosted in a WebRole on Internal Endpoint

Say I have a WCF service hosted in a web role, and it is for application internal uses only – that is, no public access to that service.

To communicate with WCF thru an internal endpoint basically is to write our own service host and provide custom client configuration.

To do this, first we declare an Internal endpoint in VS Role setting for that specific WebRole.

image

Open WCF Service project, we then need to add codes to host our service in WebRole.cs.

namespace SQLUserMgmtSvc
{
public class WebRole : RoleEntryPoint
{
// service host instance
private ServiceHost _host = null;
private void SetupTcpEndpoint()
{
//host Notification service
_host = new ServiceHost(typeof(Notification));
_host.Faulted += (sender, e) =>
{
Trace.TraceError("Host fail!");
_host.Abort();
Trace.TraceError("Host aborted");
};
//we'll expose this service via NetTcpBinding
NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.None);
//Retrieve endpoint setting via RoleEnvironment
RoleInstanceEndpoint internalEP =
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["InternalServiceEP"];
//add endpoint to service host
_host.AddServiceEndpoint(typeof(INotification), tcpBinding,
string.Format("net.tcp://{0}/Notification.svc", internalEP.IPEndpoint));
//start listening
_host.Open();
}
public override void OnStop()
{
_host.Close();
base.OnStop();
}
public override bool OnStart()
{
// To enable the AzureLocalStorageTraceListner
// uncomment relevent section in the web.config
//...omitted...

// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
SetupTcpEndpoint();
return base.OnStart();
}
}
}



Then on the client side, create a proxy via ChannelFactory class



        private static CloudSVC.INotification GetNotificationService()
{
////Create with basic http binding
//ChannelFactory<CloudSVC.INotification> factory =
// new ChannelFactory<CloudSVC.INotification>
// ("BasicHttpBinding_INotification");
//return factory.CreateChannel();

////create net.tcp internal endpoint
var remoteAddress =
RoleEnvironment.Roles["SQLUserMgmtSvc"].Instances[0].InstanceEndpoints["InternalServiceEP"].IPEndpoint;
var remoteEndpoint = new EndpointAddress(string.Format("net.tcp://{0}/Notification.svc",remoteAddress));

ChannelFactory<CloudSVC.INotification> factory =
new ChannelFactory<INotification>(new NetTcpBinding(SecurityMode.None), remoteEndpoint);
return factory.CreateChannel();
}


This is how we communicate between Roles via Internal endpoint.


However as you can see, we are retrieving remote service address via RoleEnvironment.Roles[“ROLE”].Instance[0], meaning the service is NOT load balanced.


If you do need load balance mechanism for internal services, you have to implement that in your codes, Ryan Dunn wrote a article on this.

沒有留言:

Blog Archive

About Me