I am trying to host an external facing WCF service on Azure within a worker role.
I have a solution working very nice locally, but when I try to publish it to Azure it goes into an initializing/busy/stopped loop.
The information I've found around the internet says different things:
http://www.theworkflowelement.com/2011/01/worker-role-service-hosting-faq.html (impossible)
http://code.msdn.microsoft.com/WCF-Azure-Worker-Role-on-b394df49 (possible with hack)
Other sources say it's possible, but I don't have the rep to post more than two links.
The last one hangs on busy when I try to publish it.
Anyone know how to do this, or if it really is impossible? It would be very nice to host it in a worker role, so I don't have to use the svc and web.config mess that a web role entails.
This is the code I am using:
[ServiceContract(Namespace = "")]
public interface IMyService
{
[OperationContract]
[WebGet]
string Echo(string s);
}
public class MyService : IMyService
{
public string Echo(string s)
{
return "hey " + s;
}
}
public class TestPasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
}
}
private static void StartService()
{
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEn开发者_JAVA技巧dpoints["HttpsEndpoint"];
var uri = new Uri(endpoint.Protocol + "://" + endpoint.IPEndpoint + "/myservice");
var host = new ServiceHost(typeof(MyService), uri);
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new TestPasswordValidator();
var mexBehavior = new ServiceMetadataBehavior();
mexBehavior.HttpsGetEnabled = true;
mexBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(mexBehavior);
var soapBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
soapBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpsBinding(), "mex");
host.AddServiceEndpoint(typeof(IMyService), soapBinding, "Soap");
var restBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
restBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
var restEndpoint = host.AddServiceEndpoint(typeof(IMyService), restBinding, "");
restEndpoint.Behaviors.Add(new WebHttpBehavior { HelpEnabled = true, DefaultOutgoingResponseFormat = WebMessageFormat.Json, AutomaticFormatSelectionEnabled = true, DefaultBodyStyle = WebMessageBodyStyle.WrappedRequest });
host.Open();
}
public override void Run()
{
StartService();
while (true)
{
Thread.Sleep(10000);
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
return base.OnStart();
}
I figured out why this was happening. Worker roles need to run in elevated permissions to open HTTP ports. This setting however, is not available in the role settings gui. The setting the gui shows, which I thought controlled the permissions, is Full trust/Partial trust. I guess I have no idea what that does.
The correct setting is in the ServiceDefinition.csdef file, under WorkerRole.
<Runtime executionContext="elevated" />
精彩评论