在Windows Azure Cloud上基于x86的C#控制台应用程序中的Web角色和辅助角色之外托管WCF服务

时间:2010-12-23 11:24:12

标签: c#-4.0 azure wcf-binding

我们想构建一个azure应用程序,它使用在VC ++中开发的非托管win32 DLL(我们无法为64位编译这个dll)进行一些后台处理。第一个问题是 - 这可能吗?我们已经尝试了很多方法,但没有一种方法有效。以下是我们目前正在尝试的方法。请帮助我们解决问题或建议更好的技术。

根据我们的知识,我们不能直接在WebRole或WorkerRole中使用此DLL。 为此,我们希望构建一个托管在基于x86的C#控制台应用程序中的WCF服务,该应用程序可以使用此Win32 DLL。我们将在云上启动此应用程序并托管我们的WCF服务。 通过这种方法,我们在visual studio 2010和Windows Azure SDK 1.2中开发了一个云项目,该项目在本地模拟器上运行良好。但它不是在云上运行。 到目前为止,我们能够在云上启动此应用程序和WCF服务,但问题是 在使用服务时,它会产生以下错误。

远程服务器返回错误:(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

我们正在使用BasicHTTPBinding。以下是我们的服务合同,服务类和主机应用程序的详细信息。

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

服务实施类:

[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;
        }
    }

来自WebRole的代码段。

我们正在使用WebRole的“HttpIn”端点及其端口来绑定服务。在下面的代码片段中,我们从WebRole的onStart()方法启动该控制台应用程序(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);

我们知道这个控制台应用程序在云上运行良好,并开始托管WCF服务。

以下是托管WCF服务的控制台应用程序的代码段。

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();

以下是我们在Deafault.aspx.cs页面上创建的WCF客户端的代码片段。

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();
    }

请帮助我们解决问题或提出更好的技巧。提前致谢

1 个答案:

答案 0 :(得分:0)

在黑暗中拍摄几张照片 - 是否需要在提升的特权下运行?