0
votes

We want to build an azure application which uses a unmanaged win32 DLL, developed in VC++(We can not compile this dll for 64-bit) for some background processing. The very first question is - Is this possible? We have tried many approaches, but none has worked. Below is the approach we are trying currently. Please help us solve the problem or suggest a better technique.

According to our knowledge we cannot use this DLL directly inside a WebRole or WorkerRole. For this purpose we want to build a WCF service hosted inside a x86 based C# console application which can use this Win32 DLL. We will launch this application on cloud and host our WCF service. With this approach we developed a Cloud project in visual studio 2010 and Windows Azure SDK 1.2, which is working perfectly on local emulator. But it is not running on cloud. To date we are able to launch this application and WCF service on cloud, but the problem is while consuming the service it is giving following errors.

The remote server returned an error: (404) Not Found.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.WebException: The remote server returned an error: (404) Not Found.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[WebException: The remote server returned an error: (404) Not Found.]
   System.Net.HttpWebRequest.GetResponse() +7769892
   System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +156

[EndpointNotFoundException: There was no endpoint listening at http://10.62.43.187:20000/CalculatorService/Http that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +4767763
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +1725
   emuser_WCFContract.ICalcService.Add(Int32 num1, Int32 num2) +0
   emuser_WebRole._Default.btnAdd_Click(Object sender, EventArgs e) in C:\projects\emuserWCF_HTTP\emuser_WebRole\Default.aspx.cs:39
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +154
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3691

We are using BasicHTTPBinding. Following are the details of our service contract, service class, and host application.

Service Contract:
[ServiceContract]
    public interface ICalcService
    {
        [OperationContract]
        int Add(int num1, int num2);
        [OperationContract]
        int Sub(int num1, int num2);
    }

Service Implementation Class:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                     ConcurrencyMode = ConcurrencyMode.Multiple,
                     IncludeExceptionDetailInFaults = true,
                     AddressFilterMode = AddressFilterMode.Any)]
    public class CalcService : ICalcService
    {
        public int Add(int num1, int num2)
        {
            return num1 + num2;
        }
         public int Sub(int num1, int num2)
        {
            return num1 - num2;
        }
    }

Code snippet from WebRole.

We are using “HttpIn” endpoint of WebRole and its port to bind a service. In following code snippet, we are launching that Console application from onStart() method of WebRole(WebRole.cs)

 ProcessStartInfo psi = new ProcessStartInfo(path);
    RoleInstanceEndpoint externalEndPoint =   RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["HttpIn"];
psi.Arguments = externalEndPoint.IPEndpoint.ToString();
                              Global.ExternalIp = externalEndPoint.IPEndpoint.ToString();
                              Process dllHost = Process.Start(psi);

We know that this console application starts well on cloud, and starts hosting the WCF service.

Following is the Code snippet of console application which is hosting the WCF service.

string ep = args[0]; 
        string baseAddress = "http://" + ep + "/CalculatorService"; 
        ServiceHost serviceHost = new ServiceHost(typeof(CalcService), new Uri(baseAddress));
        Console.WriteLine("WCFHost_x86 Is Started - v1.3");
        Console.WriteLine("Endpoint Received : " + ep); 
        try
        {
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            serviceHost.Description.Behaviors.Add(smb);
            BasicHttpBinding httpBinding = new BasicHttpBinding(BasicHttpSecurityMode.None); 

            serviceHost.AddServiceEndpoint(typeof(ICalcService), httpBinding, "http://" + ep + "/CalculatorService/Http");
            Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding();
            Uri mexAddress = new Uri("http://" + ep + "/CalculatorService/Mex");
            serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, mexAddress);
            mexAddress = new Uri("http://" + ep + "/CalculatorService/Http/Mex");
            serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, mexAddress);
            serviceHost.Open();
            Console.WriteLine("Service Started At Endpoint : " + baseAddress);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error In Starting WCF Host : " + ex.Message);
        }
        Console.WriteLine("Press <Enter> To Exit");
        Console.ReadLine();

Following is code snippet of WCF Client that we creating on Deafault.aspx.cs page.

private static bool initilized = false;
    private static ICalcService CalculatorClient;
    protected void Page_Load(object sender, EventArgs e)
    {
        lblService.Text = "http://" + Global.ExternalIp + "/CalculatorService/Http";
        lblExtIp.Text = Global.ExternalIp;
        if (!initilized)
        {
            BasicHttpBinding httpBinding = new BasicHttpBinding(BasicHttpSecurityMode.None);                                
            EndpointAddress endPoint = new EndpointAddress("http://" + Global.ExternalIp + "/CalculatorService/Http");                
            ChannelFactory<ICalcService> factory = new ChannelFactory<ICalcService>(httpBinding, endPoint);
            CalculatorClient = factory.CreateChannel();
            initilized = true;
        }
    }
     protected void btnAdd_Click(object sender, EventArgs e)
    {
        int num1 = Int32.Parse(txtNum1.Text);
        int num2 = Int32.Parse(txtNum2.Text);
        int result = CalculatorClient.Add(num1, num2);
        txtResult.Text = result.ToString();
    }

Please help us solve the problem or suggest a better technique. Thanks In Advance

1
This code looks about right to me... if you have the full source for your Windows Azure app and don't mind sharing, I'd be happy to give it a try and see if I can debug it. You can email me at [email protected].user94559
Hi, Thanks for your quick reply, I have provided the whole solution on following link, please download it from following url. bit.ly/elipsisRau

1 Answers

0
votes

A few shots in the dark - could it be that you require running under elevated privileges?