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

时间:2015-09-12 08:41:02

标签: asp.net wcf azure azure-web-roles azure-cloud-services

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

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

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

像这样:

try: connection = cx_Oracle.connect('user','pass','tns_name') cursor = connection.cursor() print "connected" try: query = """select * from """ .format(line_name) tmp = cursor.execute(query) results = tmp.fetchall() except: pass except: print IOError filename='{0}.csv'.format(line_name) csv_file = open(filename,'wb') if results: myFile = csv.writer(csv_file) myFile.writerows(results) else: print "null" csv_file.close()

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

  应用程序中的服务器错误。

     

连接到via   net.tcp://myservicename.cloudapp.net:811 / UserTypeService.svc超时   00:00:00之后连接尝试为0,即1   地址()。检查您频道的RemoteAddress并验证   此端点的DNS记录对应于有效的IP地址。   分配给此操作的时间可能是a的一部分   更长的超时。

我还尝试设置<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>而不是<AllowAllTraffic/>,但这没有效果。

第二次尝试: 经过一些反馈后,我尝试了一些变体,将<WhenSource ...>FixedPort设置为811,并将角色设为PortRange

port="*"

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

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

<InternalEndpoint name="Endpoint6" protocol="tcp" port="*" >
      <FixedPortRange min="811" max="811"></FixedPortRange>
  </InternalEndpoint>

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

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

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

<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>

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

<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>

1 个答案:

答案 0 :(得分: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);

        }
    }
}