【问题标题】:Self hosting WCF without config - Hard time understanding setting up endpoints没有配置的自托管 WCF - 很难理解设置端点
【发布时间】:2014-11-07 01:11:02
【问题描述】:

我已经研究了一天,在这里向各位专家寻求建议。

我有 REST 服务,它是主要的 IIS 托管服务。

此服务需要与 32 位非托管 .dll 接口。为了做到这一点,我采用了一种常见的方法,即创建一个自托管服务并对其进行调用。

在这样的背景下,我有一段时间让自托管的主机正常工作。

这是有效的代码:

static void Main(string[] args)
        {
            Uri baseAddress = new Uri("http://localhost:8080/theSvc");
            Uri mexUri = new Uri("http://localhost:8080/theSvc/mex");

            // Create the ServiceHost.
            using (ServiceHost host = new ServiceHost(typeof(ImgService), baseAddress))
            {
//                var wsHttpBinding = new WSHttpBinding();
  //              wsHttpBinding.MaxReceivedMessageSize = int.MaxValue;
    //            host.AddServiceEndpoint(typeof(IImgService), wsHttpBinding, baseAddress);

                // Enable metadata publishing.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetUrl = mexUri;
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);



                // Open the ServiceHost to start listening for messages. Since
                // no endpoints are explicitly configured, the runtime will create
                // one endpoint per base address for each service contract implemented
                // by the service.
                host.Open();

                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();

                // Close the ServiceHost.
                host.Close();
            }
        }
    }

现在...如果我取消注释这些行以增加 maxreceivedMessageSize 并从 using 语句中删除 baseAddress,我将无法再添加对服务的引用:

所以改变这个:

        using (ServiceHost host = new ServiceHost(typeof(ImgService), baseAddress))

到这里:

        using (ServiceHost host = new ServiceHost(typeof(ImgService)))

并取消注释:

//                var wsHttpBinding = new WSHttpBinding();
  //              wsHttpBinding.MaxReceivedMessageSize = int.MaxValue;
    //            host.AddServiceEndpoint(typeof(IImgService), wsHttpBinding, baseAddress);

我收到的错误是:

... -> 本地主机

There was an error downloading 'http://...:8080/theSvc/_vti_bin/ListData.svc/$metadata'.
The request failed with HTTP status 400: Bad Request.
Metadata contains a reference that cannot be resolved: 'http://...:8080/theSvc'.
Metadata contains a reference that cannot be resolved: 'http://...:8080/theSvc'.
If the service is defined in the current solution, try building the solution and adding the service reference again.

就像其他在这里发帖的人一样……我陷入了困境。非常感谢任何帮助。

【问题讨论】:

  • 您是否考虑过 WCF 的替代方法,与简单的 HTTP 服务相比,这种方法的设置往往比较复杂?
  • 如果能满足我的需求,我会 100% 全力以赴。如果我能弄清楚最后一个配置部分,我觉得我与 WCF 服务非常接近
  • 好吧,你已经被警告了 :) 说真的,我帮不了你,我小心避免 WCF
  • 纯 HTTP 和 NancyFx 甚至纯 HttpListener 都可以,除非你需要 WCF 功能。
  • 如果你包装的 dll 需要暴露的只是一个字符串,你不太可能需要 WCF,但这并不意味着你不能使用它。看看你是否让它工作或查看我提到的两个选项。

标签: c# web-services wcf self-hosting


【解决方案1】:

您似乎没有添加服务端点。

这是我用来启动 http 主机的功能,但是我将它托管在 Windows 服务中。这与您的控制台应用程序相同。但 IIS 的想法可能会有所不同。

static Uri scannerSvcBaseAddress;
static BasicHttpBinding scannerBinding;
static ServiceHost scannerHost;

public void startScannerWcfService(long eventID)
{
    try
    {
        db.writeServiceLog(eventID, "STARTUP", "=== Scanner WCF Service Starting ===");

        string addressToHostAt = ConfigurationManager.AppSettings["ScannerHostBaseAddress"];

        if (addressToHostAt != null && addressToHostAt.Trim() != string.Empty)
        {

            scannerSvcBaseAddress = new Uri(addressToHostAt);
            scannerHost = new ServiceHost(typeof(BarCodeService.ScannerService), scannerSvcBaseAddress);

            //Allows publishing of METADATA to developers when self hosted on a remote system                 
            ServiceMetadataBehavior smb = scannerHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
            {
                smb = new ServiceMetadataBehavior();
            }
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            scannerHost.Description.Behaviors.Add(smb);

            scannerHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

            scannerBinding = new BasicHttpBinding();
            scannerBinding.MaxReceivedMessageSize = 2147483647;
            scannerBinding.Security.Mode = BasicHttpSecurityMode.None;
            scannerBinding.OpenTimeout = new TimeSpan(0, 0, 10);
            scannerBinding.CloseTimeout = new TimeSpan(0, 0, 10);
            scannerBinding.SendTimeout = new TimeSpan(0, 5, 0);
            scannerBinding.ReceiveTimeout = new TimeSpan(0, Global.scanUserIdleLogout * 2, 0);

            //scannerBinding.ReliableSession.InactivityTimeout = new TimeSpan(2, 0, 0, 0);

            scannerHost.AddServiceEndpoint(typeof(BarCodeService.IScannerService), scannerBinding, "");

            var behavior = scannerHost.Description.Behaviors.Find<ServiceDebugBehavior>();
            behavior.IncludeExceptionDetailInFaults = true;


            scannerHost.Open();

            db.writeServiceLog(eventID, "STARTUP", "=== Scanner WCF Service Started ===");
        }
        else
            throw new Exception("Host Base Address not provided");
    }
    catch (Exception ex)
    {
        db.writeServiceLog(eventID, "STARTUP", string.Format("Error in ServiceManager.startScannerWcfService: {0} {1}", ex.Message, ex.StackTrace));
        throw;
    }

}

如上所述,如果您只需要公开一个字符串 WCF 可能是矫枉过正。我在 Windows 服务中使用 WCF 连接到仓库环境中的手持扫描仪,我对它的性能非常满意。虽然最初让它工作是一个巨大的痛苦。

但是由于这个问题是在 WCF 的上下文中提出的,我想我会用一个已知的工作函数来回答,它基本上可以做你想做的事情。

【讨论】:

  • 叮叮叮叮获胜者获胜者鸡肉晚餐!我喜欢 StackOverflow。非常感谢您花时间发布。这似乎解决了我的问题。现在我只需要逐行阅读并了解原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 2013-05-29
相关资源
最近更新 更多