WCF服务的内部端点不适用于Azure Web角色

Mag*_*son 6 asp.net wcf azure azure-web-roles azure-cloud-services

我有两个Web角色,其中一个运行服务层,包括与net.tcp连接的3个WCF服务,每个服务部署为端口808,810和811上的网站.

现在我希望服务层只对我的其他Web角色开放.

因此,我尝试将其中一个服务端点设置为内部,并为我的前端Web角色提供访问权限.

像这样:

<ServiceDefinition name="MagnusAzureCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6"> <WebRole name="Core.Services" vmsize="Small"> <Runtime executionContext="elevated" /> <Startup> <Task commandLine="Startup/startup.cmd" executionContext="elevated" taskType="background" /> </Startup> <Sites> <Site name="Core" physicalDirectory="C:\CoreServices"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> </Bindings> </Site> <Site name="Store" physicalDirectory="C:\StoreServices"> <Bindings> <Binding name="Endpoint3" endpointName="Endpoint3" /> </Bindings> </Site> <Site name="Users" physicalDirectory="C:\UserServices"> <Bindings> <Binding name="Endpoint4" endpointName="Endpoint4" /> </Bindings> </Site> </Sites> <ConfigurationSettings> <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" /> </ConfigurationSettings> <Endpoints> <InputEndpoint name="Endpoint1" protocol="http" port="8282" /> <InputEndpoint name="Endpoint3" protocol="http" port="81" /> <InputEndpoint name="Endpoint4" protocol="http" port="8181" /> <InputEndpoint name="Endpoint2" protocol="tcp" port="808" localPort="808" /> <InputEndpoint name="Endpoint5" protocol="tcp" port="810" localPort="810" /> <InternalEndpoint name="Endpoint6" protocol="tcp" port="811" /> </Endpoints> <Certificates> </Certificates> <Imports> <Import moduleName="RemoteAccess" /> <Import moduleName="RemoteForwarder" /> </Imports> </WebRole> <WebRole name="UIWeb" vmsize="Small"> <Runtime executionContext="elevated" /> <Startup> <Task commandLine="Startup/startup.cmd" executionContext="elevated" taskType="background" /> </Startup> <Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> </Bindings> </Site> </Sites> <ConfigurationSettings> <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" /> </ConfigurationSettings> <Endpoints> <InputEndpoint name="Endpoint1" protocol="http" port="80" /> </Endpoints> <Imports> <Import moduleName="RemoteAccess" /> </Imports> </WebRole> <NetworkTrafficRules> <OnlyAllowTrafficTo> <Destinations> <RoleEndpoint endpointName="Endpoint6" roleName="Core.Services" /> </Destinations> <WhenSource matches="AnyRule"> <FromRole roleName="UIWeb"/> </WhenSource> </OnlyAllowTrafficTo> </NetworkTrafficRules> </ServiceDefinition>

但是当尝试UserService时,似乎超时了.

'/'应用程序中的服务器错误.

通过net.tcp连接://myservicename.cloudapp.net:811/UserTypeService.svc在00:00:00后超时.连接尝试连接到1个可用地址中的0().检查通道的RemoteAddress,并验证此端点的DNS记录是否与有效的IP地址相对应.分配给此操作的时间可能是较长超时的一部分.

我也试图设置<AllowAllTraffic/>而不是<WhenSource ...>但没有效果.

第二次尝试:在一些反馈后,我尝试了一些变化来设置a FixedPortPortRange811以及听取的角色port="*".

<InternalEndpoint name="Endpoint6" protocol="tcp" port="*" >
      <FixedPortRange min="811" max="811"></FixedPortRange>
  </InternalEndpoint>
Run Code Online (Sandbox Code Playgroud)

我保留了NetworkTrafficRules,就像之前的尝试一样.

我还添加了以下代码以确保有一个动态端口的侦听器.在我的WebRole.cs文件中:

    public class WebRole : RoleEntryPoint
{
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override bool OnStart()
    {
        Trace.TraceInformation("OnStart method called. Updating information on IIS.");

        try
        {
            // Initialize method-wide variables
            var epName = "Endpoint6";
            var roleInstance = RoleEnvironment.CurrentRoleInstance;

            // Identify direct communication port
            var myPublicEp = roleInstance.InstanceEndpoints[epName].PublicIPEndpoint;
            Trace.TraceInformation("IP:{0}, Port:{1}", myPublicEp.Address, myPublicEp.Port);

            // Identify public endpoint
            var myInternalEp = roleInstance.InstanceEndpoints[epName].IPEndpoint;

            // Create socket listener
            var listener = new Socket(
              myInternalEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            // Bind socket listener to internal endpoint and listen
            listener.Bind(myInternalEp);
            listener.Listen(10);
            Trace.TraceInformation("Listening on IP:{0},Port: {1}",
              myInternalEp.Address, myInternalEp.Port);

            while (true)
            {
                // Block the thread and wait for a client request
                Socket handler = listener.Accept();
                Trace.TraceInformation("Client request received.");

                // Define body of socket handler
                var handlerThread = new Thread(
                  new ParameterizedThreadStart(h =>
                  {
                      var socket = h as Socket;
                      Trace.TraceInformation("Local:{0} Remote{1}",
              socket.LocalEndPoint, socket.RemoteEndPoint);

                      // Shut down and close socket
                      socket.Shutdown(SocketShutdown.Both);
                      socket.Close();
                  }
                ));

                // Start socket handler on new thread
                handlerThread.Start(handler);
            }
        }
        catch (Exception e)
        {
            Trace.TraceError("Caught exception in run. Details: {0}", e);
        }
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        return base.OnStart();
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个注意事项是,由于服务运行三个不同的WCF项目站点,因此呼叫服务使用端口811来查找正确的服务.我正在调用的服务也使用一个指定的端口号,如果它突然变得动态,我认为这可能是一个问题.调用服务看起来像这样:

<endpoint address="net.tcp://myservicename.cloudapp.net:811/UserTypeService.svc"
      behaviorConfiguration="ClientContextEndpointBehavior" binding="netTcpBinding"
      bindingConfiguration="NetTcpBinding_FrameworkService" contract="Users.Services.IPersonTypeService"
      name="Tcp">
    <identity>
      <dns value="The Certificate Name" />
    </identity>
  </endpoint>
Run Code Online (Sandbox Code Playgroud)

在接收(内部)WebRole站点上,我有以下类型的配置.

<service name="Core.Services.Logging.LoggingService" behaviorConfiguration="coreServiceBehavior">
<endpoint address="net.tcp://localhost:808/LoggingService.svc" 
              behaviorConfiguration="ContextEndpointBehavior" 
              binding="netTcpBinding"
              bindingConfiguration="NetTcpBinding1" 
              contract="Core.Logging.ILoggingService">
      <identity>
        <dns value="The Certificate Name" />
      </identity>
    </endpoint>
Run Code Online (Sandbox Code Playgroud)

端口811上的另一个WCF站点:

<service name="Users.Services.PersonTypeService">
<endpoint address="net.tcp://localhost:811/UserTypeService.svc" binding="netTcpBinding" bindingConfiguration="NetTcpServiceBinding1" behaviorConfiguration="ServerContextEndpointBehavior" contract="Users.Services.IUserTypeService">
  <identity>
    <dns value="The Certificate Name" />
  </identity>
</endpoint>

<endpoint address="mex" binding="mexTcpBinding" kind="mexEndpoint">
  <identity>
    <dns value="localhost" />
  </identity>
</endpoint>
Run Code Online (Sandbox Code Playgroud)

小智 0

您可以使用内部端点 IP 地址而不是外部地址。这是一个例子:

foreach (RoleInstance roleInst in RoleEnvironment.CurrentRoleInstance.Role.Instances)
{
    // Skip local role instance
    if (RoleEnvironment.CurrentRoleInstance.Id == roleInst.Id) continue;

    if (roleInst.Role.Name == "My Cool Role")
    {
        foreach (RoleInstanceEndpoint roleInstEndpoint in roleInst.InstanceEndpoints.Values)
        {
            // Get endpoint address using the internal endpoint's IP address
            if (roleInstEndpoint.Protocol == "tcp")
                SendRequest(roleInstEndpoint.IPEndpoint.Address.ToString(), command);

        }
    }
}
Run Code Online (Sandbox Code Playgroud)