我正在尝试在Windows服务中托管WCF net.pipe服务。我在 Windows 服务的 OnStart()
函数中用代码定义服务。我也以类似的方式创建客户端 - 在代码中。
我看到过这个问题,但它似乎总是只用于在app/web.config文件中定义NetNamedPipe的情况。
尝试调用服务时,出现错误:
System.ServiceModel.ProtocolException: The requested upgrade is not supported by 'net.pipe://localhost/manager'. This could be due to mismatched bindings (for example security enabled on the client and not on the server).
Server stack trace:
at System.ServiceModel.Channels.ConnectionUpgradeHelper.DecodeFramingFault(ClientFramingDecoder decoder, IConnection connection, Uri via, String contentType, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at MyClientApp.IManager.HelloWorld()
这是我的代码:
//Service Contract:
[ServiceContract]
public interface IManager
{
[OperationContract]
string HelloWorld();
}
//Service
public class Manager : IManager
{
public string HelloWorld()
{
return "Hello to you too!";
}
}
//Defining and starting the Net.Pipe Service from the Windows Service
public partial class MyWindowsService : ServiceBase
{
public MyWindowsService()
{
InitializeComponent();
}
private ServiceHost m_serviceHost;
protected override void OnStart(string[] args)
{
try
{
m_serviceHost = new ServiceHost(typeof(Manager), new Uri("net.pipe://localhost"));
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
m_serviceHost.AddServiceEndpoint(typeof(IManager), binding, "manager");
m_serviceHost.Open();
}
catch (Exception ex)
{
EventLog("MyWindowsService", ex.ToString(), EventLogEntryType.Error);
}
}
}
//The client proxy
public class ManagerProxy : ClientBase<IManager>
{
public ManagerProxy()
: base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IManager)),
new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/manager"))) { }
public string InvokeHellowWorld()
{
return Channel.HelloWorld();
}
}
接口位于类库项目中,在主机应用程序(Windows 服务)和尝试调用服务的客户端应用程序之间共享。
Service类和 OnStart 函数位于 Windows Service 项目中。
服务代理位于客户端项目中(当然,客户端项目与 Windows 服务在同一台计算机上运行)。
另外,每当我尝试使用代理时,我发现它State == CommunicationState.Faulted
。然后我关闭/中止它,并创建一个new ManagerProxy()
.然后Created
ManagerProxy
的状态。我尝试调用HelloWorld
并获得上述Exception
.
下次我尝试使用它时 - 它的状态再次Faulted
并且该过程重复。
我能看到的唯一区别是,在服务器端创建绑定时明确没有安全模式binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
,而在客户端没有安全模式new NetNamedPipeBinding()
。异常消息确实提到安全性是潜在的不匹配。
System.ServiceModel.Protocol异常:请求的升级不是 由'net.pipe://localhost/manager'支持。这可能是由于 不匹配的绑定(例如,在客户端上启用的安全性和 不在服务器上)。
刚刚在这里检查,默认安全模式不是NetNamedPipeSecurityMode.None
它是NetNamedPipeSecurityMode.Transport
.所以那里有不匹配。
如果上述解决方案都不适合您,请尝试从终端节点中删除标识,如下所示:
<endpoint
address="net.tcp://127.0.0.1/FacilitySchedulesService/FacilitySchedulesService.svc"
binding="netTcpBinding"
bindingConfiguration="FacilityScheduleDSTCP"
contract="FacilitySchedules.IFacilitySchedulesService"
name="FacilityScheduleDSTCP">
<!--
<identity>
<userPrincipalName value="abc" />
</identity>
-->
</endpoint>
另一种情况可能是,在绑定配置中选择的安全模式使用了不正确的子节点名称。在下面的示例中,使用了"消息"节点,尽管选择了传输模式,但会导致"不支持请求的升级"异常:
<security mode="Transport">
<message clientCredentialType="Certificate"/>
</security>