Mono 中的自托管 WCF 服务

Posted

技术标签:

【中文标题】Mono 中的自托管 WCF 服务【英文标题】:Self hosted WCF service in Mono 【发布时间】:2013-02-27 02:32:23 【问题描述】:

我目前正在开发一个 C# 项目,它是一个控制台应用程序,其中托管了 WCF 肥皂服务。

下面是我用来打开主机的代码。

var baseAddress = new Uri(Configuration.soapServerSettings.soapServerUrl);
var host = new ServiceHost(typeof(SoapServer), baseAddress);
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();

var meta = new ServiceMetadataBehavior()

    HttpGetEnabled = true,
    HttpGetUrl = new Uri("", UriKind.Relative)
;

host.Description.Behaviors.Add(meta);

var debugBehaviour = new ServiceDebugBehavior()

    HttpHelpPageEnabled = true,
    HttpHelpPageUrl = new Uri("", UriKind.Relative),
    IncludeExceptionDetailInFaults = true
;

ServiceEndpoint endpnt = host.AddServiceEndpoint(
    typeof(ISoapInterface),
    basicHttpBinding,
    "EmailServer");

host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
host.Description.Behaviors.Add(debugBehaviour);
host.Open();

这在 Windows 上运行良好,但在 Linux 上,当我浏览它时,我收到以下消息:

XmlSchema 错误:命名项 http://schemas.microsoft.com/2003/10/Serialization/:anyType 是 已包含在模式对象表中。考虑设置 MONO_STRICT_MS_COMPLIANT 为“是”以模仿 MS 实现。有关的 架构项 SourceUri: ,第 3 行,第 3 位。

我不知道从哪里开始研究这个问题。

感谢您提供的任何帮助

更新: 根据 Rob Goodwins 的建议,我添加了 MONO_STRICT_MS_COMPLIANT 作为环境变量,这似乎确实有效,我可以访问该服务。但是,我现在遇到了一个不同的问题。我有一个 php 页面,它每隔几秒钟执行几个请求,但一分钟后,我的应用程序崩溃了。

我得到以下异常:

此 XmlWriter 在此状态下不接受 StartTag 错误。在 System.Xml.XmlTextWriter.WriteStartElement(System.String 前缀, System.String localName, System.String namespaceUri) [0x00000] in :0 在 System.Xml.DefaultXmlWriter.WriteStartElement(System.String 前缀, System.String localName, System.String ns) [0x00000] in :0 在 System.Xml.XmlWriter.WriteStartElement (System.String localName, System.String ns) [0x00000] in :0 at System.ServiceModel.Logger.TraceCore (TraceEventType eventType, Int32 id, Boolean hasRelatedActivity, Guid relatedActivity, System.Object[] 数据)[0x00000] in :0 at System.ServiceModel.Logger.LogMessage (System.ServiceModel.Diagnostics.MessageLogTraceRecord 日志)[0x00000] 在 System.ServiceModel.Logger.LogMessage 的 :0 中 (MessageLogSourceKind sourceKind, System.ServiceModel.Channels.Message& msg, Int64 maxMessageSize) [0x00000] 在 :0 处 System.ServiceModel.Channels.Http.HttpRequestContext.InternalReply (System.ServiceModel.Channels.Message 消息,TimeSpan 超时)[0x00000] 在 :0 在 System.ServiceModel.Channels.Http.HttpRequestContext.Reply (System.ServiceModel.Channels.Message 消息,TimeSpan 超时)[0x00000] 在 :0 在 System.ServiceModel.Dispatcher.MessageProcessingContext.Reply(布尔值 useTimeout) [0x00000] in :0 at System.ServiceModel.Dispatcher.OperationInvokerHandler.Reply (System.ServiceModel.Dispatcher.MessageProcessingContext mrc,布尔值 useTimeout) [0x00000] in :0 at System.ServiceModel.Dispatcher.OperationInvokerHandler.ProcessRequest (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] 在 :0 处 System.ServiceModel.Dispatcher.BaseRequestProcessorHandler.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] 在 :0 处 System.ServiceModel.Dispatcher.BaseRequestProcessorHandler.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] 在 :0 处 System.ServiceModel.Dispatcher.HandlersChain.ProcessRequestChain (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] 在 :0 处 System.ServiceModel.Dispatcher.BaseRequestProcessor.ProcessRequest (System.ServiceModel.Dispatcher.MessageProcessingContext mrc) [0x00000] 在 :0

未处理的异常:System.InvalidOperationException:此 XmlWriter 在此状态下不接受 StartTag 错误。在 System.Xml.XmlTextWriter.WriteStartElement(System.String 前缀, System.String localName, System.String namespaceUri) [0x00000] in :0 在 System.Xml.DefaultXmlWriter.WriteStartElement(System.String 前缀, System.String localName, System.String ns) [0x00000] in :0 在 System.Xml.XmlWriter.WriteStartElement (System.String localName, System.String ns) [0x00000] in :0 at System.ServiceModel.Logger.TraceCore (TraceEventType eventType, Int32 id, Boolean hasRelatedActivity, Guid relatedActivity, System.Object[] 数据)[0x00000] in :0 at System.ServiceModel.Logger.Log (TraceEventType eventType, System.String 消息,System.Object[] args) [0x00000] in :0 在 System.ServiceModel.Logger.Error (System.String 消息,System.Object[] args) [0x00000] in :0 at System.ServiceModel.Dispatcher.ListenerLoopManager.ProcessErrorWithHandlers (IChannel ch, System.Exception ex, System.ServiceModel.Channels.Message& res) [0x00000] in :0 at System.ServiceModel.Dispatcher.ListenerLoopManager.ProcessRequest (IRplyChannel 回复,System.ServiceModel.Channels.RequestContext rc) [0x00000] 在 :0 处 System.ServiceModel.Dispatcher.ListenerLoopManager.TryReceiveRequestDone (IAsyncResult 结果) [0x00000] in :0

我似乎也无法通过 VS2010 WCF 测试客户端访问该服务,它不会出错,它只是坐在那里,进度条处于 50% 并且没有进一步。

在 apache 错误日志中我收到以下错误:

System.ArgumentException: 应该类似于 [[主机名:]端口:]VPath:真实路径在 Mono.WebServer.ApplicationServer.AddApplicationsFromCommandLine (System.String 应用程序)[0x00000] in :0 at (包装器远程调用与检查) Mono.WebServer.ApplicationServer:AddApplicationsFromCommandLine (字符串)在 Mono.WebServer.Apache.Server.RealMain (System.String[] args,布尔根,IApplicationHost ext_apphost,布尔安静) [0x00000] in :0 at (wrapper remoting-invoke-with-check) Mono.WebServer.Apache.Server:RealMain (string[],bool,Mono.WebServer.IApplicationHost,bool) 在 Mono.WebServer.Apache.Server.Main (System.String[] args) [0x00000] 在 :0 [错误] 致命的未处理异常: System.ArgumentException:应该类似于 [[主机名:]端口:]VPath:真实路径在 Mono.WebServer.ApplicationServer.AddApplicationsFromCommandLine (System.String 应用程序)[0x00000] in :0 at (包装器远程调用与检查) Mono.WebServer.ApplicationServer:AddApplicationsFromCommandLine (字符串)在 Mono.WebServer.Apache.Server.RealMain (System.String[] args,布尔根,IApplicationHost ext_apphost,布尔安静) [0x00000] in :0 at (wrapper remoting-invoke-with-check) Mono.WebServer.Apache.Server:RealMain (string[],bool,Mono.WebServer.IApplicationHost,bool) 在 Mono.WebServer.Apache.Server.Main (System.String[] args) [0x00000] 在 :0

更新 2: 除了我只能在本地访问该服务外,我现在似乎可以使用它了。 IE。可以在本地访问 Web 服务,并且功能可以执行应有的操作,但我无法从另一台 PC 访问它。 IE。我正在尝试使用来自开发 PC 的开发 PC 的 WCF 测试客户端访问 Mono 服务器上的 WCF 服务,然后我得到以下输出:

错误:无法从http://192.168.1.74:6525/ 获取元数据如果这样 是您拥有的 Windows (R) Communication Foundation 服务 访问,请检查您是否已在 指定的地址。如需帮助启用元数据发布,请 请参阅 MSDN 文档 http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata交流 错误 URI:http://192.168.1.74:6525/ 元数据包含 无法解析的引用:'http://192.168.1.74:6525/'. 内容类型应用程序/soap+xml; charset=utf-8 不受支持 服务http://192.168.1.74:6525/。客户端和服务绑定 可能不匹配。远程服务器返回错误:(415) 预期的内容类型'text/xml; charset=utf-8' 但得到了 '应用程序/肥皂+xml; charset=utf-8'.HTTP GET 错误 URI: http://192.168.1.74:6525/文档看懂了,但是可以 不被处理。 - WSDL 文档包含无法访问的链接 得到解决。 - 下载时出错 'http://localhost:6525/?xsd=xsd0'。 - 无法连接到遥控器 服务器 - 无法建立连接,因为目标机器 127.0.0.1:6525 主动拒绝。

更新 3: 经过进一步测试,看起来好像一次对服务进行了许多调用。在使用该服务的浏览器页面上不断刷新似乎会使它崩溃。

Mono 中的System.ServiceModel.Logger.TraceCore 似乎有问题。有没有办法禁用这部分单声道,这样我就不会受到这个问题的影响。

【问题讨论】:

您是否尝试过使用错误消息中的建议,将 MONO_STRICT_MS_COMPLIANT 设置为 yes ?查看这篇博文erictummers.wordpress.com/2012/01/24/wsdl-in-mono 我没找到这个设置在哪里 我相信是环境变量 @RobGoodwin 你是对的,它现在的工作量越来越少,除非在几次请求后它崩溃了。我已经用更多细节更新了问题 Mono 是开源的,抓起该死的 TraceCore.cs 文件并尝试修复错误 【参考方案1】:

似乎托管服务器可能存在一些与权限相关的问题,请检查一下授予特定端口的权限。希望这可能有用。

【讨论】:

其他客户端可以连接到它,比如vs2010中的WCF测试客户端

以上是关于Mono 中的自托管 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

自托管 WCF 服务中的 HTTP 413 请求实体太大

如何让我的自托管 WCF 服务不尝试保留 localhost 以外的 url?

强大的自托管服务器的最佳选择:WCF 与 ASP.NET Web Api

具有多个合同的 Mono WCF 休息服务“配置文件中未定义端点”

如何为自托管 WCF 服务启用跨域调用

自托管 WCF 服务和 basicHttpBinding:绑定不提供表示调用者的 Windows 标识