WCF端口没有收听

时间:2017-04-12 17:42:55

标签: c# .net wcf tcp

更新

服务正在运行并且在任务管理器中有一个pid但是当我运行netstat -ano | find pid#时没有返回任何内容 - 端口没有监听。

此外,如果我运行netstat -ap tcp,则未列出端口。

我真的不知道如何解决这个问题。总而言之,您不必阅读我以前的帖子:

  • 我的WCF服务在localhost(即同一服务器上的服务和客户端)下完美运行
  • 当我将服务发布到生产服务器时,该服务安装正常,但8523端口不会监听
  • 我已经审核了几篇类似的帖子,但没有一个对我有用
  • 这是我尝试的第一个WCF项目,所以我已经耗尽了我的知识,我无法在互联网上找到更多的例子来尝试
  • 此时我将非常感谢任何指针

环境

  • 开发:Windows 7
  • Visual Studio:2015
  • 生产服务器:Windows Server 2008 R2 Datacenter
  • IIS版本7.5.7600.16385

简介

我已经研究了这个问题几天了,虽然我在Stack Overflow上发现了许多类似的问题,但这些问题都没有解决我的问题;因此,我不认为这是重复的,如果有人试图像我一样按照引用的Microsoft教程,它将特别有用

问题详情

我已经关注了这篇微软文章"如何:使用TCP"在Windows服务中托管WCF;在https://msdn.microsoft.com/en-us/library/ff649818.aspx

创建解决方案后,它在Visual Studio localhost环境中的开发计算机上运行完美。本教程建议您创建一个测试客户端来访问WCF解决方案,并且测试客户端可以成功运行

当我在生产计算机(Windows Server 2008)中发布WCF服务和Windows服务时,它会再次安装而不会出错。以下是我遵循的步骤:

IIS设置

  • 将net.tcp添加到已启用的协议

  • 激活' Windows Communication Foundation非HTTP激活'

  • 将net.tcp的绑定更改为8532

  • 确保' Net.Tcp侦听器适配器'正在运行

在防火墙中打开8532端口

浏览到WindowsService1.exe所在项目的bin目录,并以管理员身份运行exe

打开命令以管理员身份提示并运行Installutil WindowsService1.exe

Localhost(Visual Studio中的开发环境)与生产环境

之间的差异

localhost WCF系统和生产系统之间的唯一变化是我更改了app.conf中的baseAddress

  • "的net.tcp://本地主机:8523 / CustomWCFService"

  • "的net.tcp://10.2.1.1:8523 / CustomWCFService"

这是部署的app.conf



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyCustomServiceLib.CustomServiceLib">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
          contract="MyCustomServiceLib.ICustomServiceLib">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://10.2.1.1:8523/CustomWCF" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
&#13;
&#13;
&#13;

添加服务参考

当我尝试在将使用WCF服务的应用程序中添加服务引用时。我收到这个错误:

  

从地址下载元数据时出错。请   确认您输入了有效地址

当我点击&#34;详情&#34;我明白这一点:

  

无法识别URI前缀。元数据包含一个引用   无法解决:&#39; net.tcp://10.2.1.1:8523 / CustomWCF&#39;。不能   连接到net.tcp://10.2.1.1:8523 / CustomWCF。连接尝试   持续时间为00:00:01.0312368。 TCP错误代码10061:否   可以建立连接,因为目标机器主动拒绝   它10.2.1.1:8523。由于目标,无法建立连接   机器主动拒绝它10.2.1.1:8523如果服务定义在   当前的解决方案,尝试构建解决方案并添加服务   再次参考。

我尝试了什么

在论坛上提出的许多其他WCF问题似乎都是关于让服务在localhost中工作,这对我不适用,因为我创建的解决方案在开发环境中完美运行。

有些答案建议在项目中启用tcp端口共享,但是当我尝试在我的解决方案中添加此代码时,我会收到一条错误消息“#34;不允许&#34;。

其他问题表明,网址必须在生产服务器上注册,但不起作用。

在尝试了我能找到的所有论坛建议并尝试纠正我认为错误的所有内容后,我仍然没有运气。

非常感谢任何建议或指示

2 个答案:

答案 0 :(得分:0)

我没有让WCF在过去使用配置文件。我总是在代码中创建绑定。

gist确实有效。

重要的部分是NetTcpBinding

 netTcpBinding = new NetTcpBinding
                            {
                                MaxReceivedMessageSize = int.MaxValue,
                                MaxBufferPoolSize = int.MaxValue,
                                Security = new NetTcpSecurity
                                           {
                                               Mode = SecurityMode.None,
                                               Transport = new TcpTransportSecurity()
                                           }
                            };

此外,我不会指定IP,而是让WCF将其绑定到计算机上的每个IP地址。

serviceHost.AddServiceEndpoint(typeof(ITestService), netTcpBinding, string.Format("{1}://0.0.0.0:{0}/", port, "net.tcp"));

这并不妨碍您输入特定的IP,我通常不这样做。

如果你想在IIS中运行它,你必须做更多的工作。 IIS并不真的希望您托管未受http绑定的WCF服务器。

创建ServiceHost后,您需要做一些额外的工作

 var serviceBehavior = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();

if (serviceBehavior == null) return;

serviceBehavior.HttpGetEnabled = false;
serviceBehavior.HttpsGetEnabled = false;

答案 1 :(得分:0)

我已添加此帖子以详细说明将David Basarab建议更改添加到我的WCF服务库项目的结果。再次感谢大卫的帖子,但不幸的是我无法让它发挥作用。实际上它甚至没有在Visual Studio中的localhost下运行。大卫提到它对他有用,所以我可能在某个地方犯了错误。希望我在这里提供的细节能够产生一些额外的指针,指出我做错了什么或帮助其他尝试David的方法。在创建解决方案时,我尝试保留Visual Studio的默认值,但David的更改除外。

服务参考错误

当我尝试在与Windows服务和实际WCF服务库相同的计算机上的测试客户端中添加服务引用时收到的错误:

The URI prefix is not recognized. Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:8523/Service1'. Could not connect to net.tcp://localhost:8523/Service1. The connection attempt lasted for a time span of 00:00:02.0028015. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:8523. No connection could be made because the target machine actively refused it 127.0.0.1:8523 If the service is defined in the current solution, try building the solution and adding the service reference again.

WCF库代码

IService1.cs单位

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CustomServiceLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Add your service operations here
    }

    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    // You can add XSD files into the project. After building the project, you can directly use the data types defined there, with the namespace "CustomServiceLibrary.ContractType".
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}

Service1.cs代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace CustomServiceLibrary
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}

Server.cs类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace CustomServiceLibrary
{
    class Server
    {
        private readonly ushort port;
        private readonly Service1 Service1;
        private NetTcpBinding netTcpBinding;
        private ServiceHost serviceHost;

        public Server(ushort port)
        {
            this.port = port;
            Service1 = new Service1();
        }

        public void Start()
        {
            try
            {
                CreateServiceHost();

                CreateBinding();

                AddEndpoint();

                serviceHost.Open();

                Console.WriteLine("Service has been opended");

                ConfigureHTTP();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ERROR      := {ex.Message}");
                Console.WriteLine($"StackTrace := {ex.StackTrace}");
            }
        }

        private void AddEndpoint()
        {
            serviceHost.AddServiceEndpoint(typeof(IService1), netTcpBinding, string.Format("{1}://0.0.0.0:{0}/", port, "net.tcp"));
        }

        private void ConfigureHTTP()
        {
            var serviceBehavior = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();

            if (serviceBehavior == null) return;

            serviceBehavior.HttpGetEnabled = false;
            serviceBehavior.HttpsGetEnabled = false;
        }

        private void CreateBinding()
        {
            netTcpBinding = new NetTcpBinding
            {
                MaxReceivedMessageSize = int.MaxValue,
                MaxBufferPoolSize = int.MaxValue,
                Security = new NetTcpSecurity
                {
                    Mode = SecurityMode.None,
                    Transport = new TcpTransportSecurity()
                }
            };
        }

        private void CreateServiceHost()
        {
            serviceHost = new ServiceHost(Service1);
        }
    }
}

摘要

除了David添加到项目中的更改之外,我所做的其他所有操作都与使用App.conf配置的上一次部署所做的相同。我刚刚按照https://msdn.microsoft.com/en-us/library/ff649818.aspx中的Microsoft文章“如何:使用TCP在Windows服务中托管WCF”中的说明进行操作