简体   繁体   English

以工作角色主持WCF,超时

[英]Host WCF in the Worker Role, Timeout

Basically, I'm following this: GUIDE 基本上,我正在遵循: GUIDE

What I want is to publish my Cloudapp to azure with one web role and one worker role . 我想要的是将Cloudapp发布到具有一个Web角色和一个Worker角色的天蓝色数据库。

Worker role 工人角色

I'm hosting a WCF service in my worker role where all the sql communication will happen, (DTO objects). 我在我的工作人员角色中托管WCF服务,在该角色中将发生所有sql通信(DTO对象)。

Web role 网络角色

My web role project is just a normal MVC app that has a service reference to the WCF service. 我的Web角色项目只是一个普通的MVC应用程序,具有对WCF服务的服务引用。 For an example, if a user wants to register, the data is sent to the WCF service which then sends it to the DB. 例如,如果用户要注册,则将数据发送到WCF服务,然后将其发送到DB。

Problem 问题

Error message: 错误信息:

An exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll but was not handled in user code

Additional information: The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.

I also got a timeout error before which I can't seem to reproduce anymore.. 我也遇到超时错误,在此之前我似乎无法重现。

I have followed the guide very thoroughly. 我已经非常彻底地遵循了指南。 The one thing that is different is that I would like to host them in one publish, not two. 与众不同的一件事是,我希望将它们托管在一个发布中,而不是两个。 Also, the guy publish the project by clicking on packages which I don't, (I click on publish button). 另外,这个家伙通过单击我不喜欢的程序包来发布项目(我单击“发布”按钮)。

I'm all out of ideas. 我全都没主意了。 I have only found two guides about hosting your WCF service in a worker role, the one I'm following now and THIS one. 我仅找到了两个有关以角色角色托管WCF服务的指南,我现在正在关注的指南,也是这本指南 Both are very outdated and doesn't really do what I want to do. 两者都非常过时,并没有真正做到我想做的事。 Both guides host the WCF service as a standalone Cloudapp. 这两个指南都将WCF服务作为独立的Cloudapp托管。 What I want is to publish both the worker role and the web role in the same solution, one publish. 我要的是公布这两种辅助角色,并在同一个解决方案Web角色, 一个发布。

If you have any suggestions, please leave them here. 如果您有任何建议,请留在这里。 I appreciate all the help I can get. 我感谢我能获得的所有帮助。 Thank you very much. 非常感谢你。

/Dying programmer /垂死的程序员

EDIT 1 - CODE - 编辑1-代码-

INTERFACE & IMPLEMENTATION 接口与实现

namespace Fildela_Worker
{
    [ServiceContract]
    public interface IFildelaService
    {
        [OperationContract]
        void InsertUser(UserDTO user);
    }
}
[System.ServiceModel.ServiceBehaviorAttribute(IncludeExceptionDetailInFaults=tru‌​e)]
public class FildelaService : IFildelaService
    {
        DataLayer DB = new DataLayer();

        public void InsertUser(UserDTO user)
        {
            User newUser = new User(user.FirstName.ToLower().Trim(), user.LastName.ToLower().Trim(),
                user.Email.ToLower().Trim(), user.Password.Trim(), user.PasswordSalt.Trim(), user.AgreeUserAgreement);

            DB.User.Add(newUser);
            DB.SaveChanges();
        }
}

SERVICE DEFINITION 服务定义

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Fildela_Web.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2014-01.2.3">
  <WebRole name="Fildela Web" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
  </WebRole>
  <WorkerRole name="Fildela Worker" vmsize="Small">
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <Endpoints>
      <InputEndpoint name="port" protocol="tcp" port="9001" />
      <InputEndpoint name="mexport" protocol="tcp" port="8001" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>

WORKER ROLE ONSTART: 上手的工人角色:

public override bool OnStart()
    {
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        // Create the host
        ServiceHost host = new ServiceHost(typeof(FildelaService));

        // Read config parameters
        string hostName = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["port"].IPEndpoint.Address.ToString();
        int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["port"].IPEndpoint.Port;
        int mexport = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["mexport"].IPEndpoint.Port;

        // Create Metadata
        ServiceMetadataBehavior metadatabehavior = new ServiceMetadataBehavior();
        host.Description.Behaviors.Add(metadatabehavior);

        Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
        string mexendpointurl = string.Format("net.tcp://{0}:{1}/FildelaServiceMetadata", hostName, 8001);
        host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, mexendpointurl, new Uri(mexendpointurl));

        // Create end point
        string endpointurl = string.Format("net.tcp://{0}:{1}/FildelaService", hostName, 9001);
        host.AddServiceEndpoint(typeof(IFildelaService), new NetTcpBinding(SecurityMode.None), endpointurl, new Uri(endpointurl));

        // Open the host
        host.Open();

        // Trace output
        Trace.WriteLine("WCF Listening At: " + endpointurl);
        Trace.WriteLine("WCF MetaData Listening At: " + mexendpointurl);

        return base.OnStart();
    }

MVC WEB.CONFIG: MVC WEB.CONFIG:

<system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IFildelaService">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://MYADDRESS.cloudapp.net:9001/FildelaService"
        binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IFildelaService"
        contract="FildelaServiceReference.IFildelaService" name="NetTcpBinding_IFildelaService" />
    </client>
....

MVC PROXY USE: MVC代理用途:

FildelaServiceClient proxy = new FildelaServiceClient();

                                UserDTO newUser = new UserDTO()
                                {
parameters....
                                };

                                //Insert user
proxy.InsertAccountOwner(newUser);

EDIT 2 - CODE - 编辑2-代码-

Worker role 工人角色

public override bool OnStart()
    {
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        StartWCFHost();

        return base.OnStart();
    }

private void StartWCFHost()
{
    var baseaddress = string.Format("net.tcp://{0}/", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["FildelaService"].IPEndpoint);
    var host = new ServiceHost(typeof(FildelaService), new Uri(baseaddress));
    host.AddServiceEndpoint(typeof(IFildelaService), new NetTcpBinding(SecurityMode.None), "Database");
    host.Open();
}

ServiceDefinition 服务定义

<WorkerRole name="Fildela Worker" vmsize="Small">
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <Endpoints>
      <InternalEndpoint name="FildelaService" protocol="tcp" />
    </Endpoints>
  </WorkerRole>

Controller 调节器

private EndpointAddress GetRandomEndpoint()
    {
        var endpoints = RoleEnvironment.Roles["Fildela Worker"].Instances.Select(i => i.InstanceEndpoints["FildelaService"].IPEndpoint).ToArray();
        var r = new Random(DateTime.Now.Millisecond);
        return new EndpointAddress(string.Format("net.tcp://{0}/Database", endpoints[r.Next(endpoints.Count() - 1)]));
    }





[HttpGet]
    [AllowAnonymous]
    public ViewResult Contact()
    {
        var factory = new ChannelFactory<IFildelaService>(new NetTcpBinding(SecurityMode.None));
        factory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
        var channel = factory.CreateChannel(GetRandomEndpoint());

        List<CategoryDTO> contactCategories = channel.GetContactCategories().ToList();

        return View(contactCategories);
    }

First, you have the contract and service , to host your service delete all the code you have added to your OnStart methode and add this methode 首先,您具有合同和服务,要托管服务,请删除添加到OnStart方法中的所有代码,然后添加此方法

 private void StartWCFHost()
    {
        var baseaddress = string.Format("net.tcp://{0}/", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["port"].IPEndpoint);
        var host = new ServiceHost(typeof(FildelaService), new Uri (baseaddress));
        host.AddServiceEndpoint(typeof(IFildelaService), new NetTcpBinding(SecurityMode.None), "Inserter");
        host.Open();
    }

That is it just call this method from your OnStart method and the host is done 就是从您的OnStart方法调用此方法,并且主机已完成

Now the question is about consuming the webservice 现在的问题是关于使用Web服务

in your controller when you are calling the webservice add this code (we're creating a Channel factory no need to add service reference) 在控制器中,当您调用Web服务时,请添加以下代码(我们正在创建Channel工厂,无需添加服务引用)

First add this method to your controller 首先将此方法添加到您的控制器

 private EndpointAddress GetRandomEndpoint()
    {
        var endpoints= RoleEnvironment.Roles["PutWorkerRoleName"].Instances.Select(i=>i.InstanceEndpoints["port"].IPEndpoint).ToArray();
        var r = new Random(DateTime.Now.Millisecond);
        return new EndpointAddress(string.Format("net.tcp://{0}/Inserter", endpoints[r.Next(endpoints.Count() - 1)]));
    }

then add this code to call the service in your controller method(since you're using MVC) 然后添加此代码以在控制器方法中调用服务(因为您正在使用MVC)

 var factory = new ChannelFactory<IFildelaService>(new NetTcpBinding(SecurityMode.None));
        var channel = factory.CreateChannel(GetRandomEndpoint());
        channel.InsertAccountOwner(newUser);

I may have forgotten to rename some variables from my working project so feel free to verify the conformity of your code 我可能忘记了在工作项目中重命名某些变量,因此可以随时验证您的代码是否符合要求

Update 更新

I uploaded the project to my github : Worker Role WCF host+Web Role 我将项目上传到了我的github: Worker Role WCF host + Web Role

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM