我已經開發了一個WCF雙工服務和Windows Winforms客戶端通過net.tcp雙工綁定進行通信的連接器。在IIS 7中使用net.tcp綁定承載WCF服務(從外部無法訪問)
兩者都在我的LAN上進行通信並正常工作,WCF服務在Windows 8工作站上的IIS 7上託管。
然後,我嘗試在運行Windows Server 2008 R2的租用專用服務器上使用固定IP地址((94.23.220.199),運行IIS 7和.Net 4.5.2)在Web上託管WCF服務。
WCF服務已安裝在/ ScgBroadcastorService虛擬路徑上,並且net.tcp協議已被激活。 (實際上,所有的IIS配置都與我局域網上的個人IIS完全相同)。因此,應該可以從外部訪問以下URL:「http://94.23.220.199/ScgBroadcastorService/Service.svc」。
如果您從您的瀏覽器訪問此鏈接,您將通過兩個wsdl鏈接獲得正確的「ScgBroadcastorService服務」頁面。 (這些鏈接正確地指「94.23.220.199」的IP地址。
如果一個用戶點擊此鏈接一個正確獲取WSDL XML文檔。
如此以來,WSDL文檔可以從外部訪問,我期望客戶端能夠與WCF服務進行通信。
但是,如果我啓動客戶端,我會得到以下異常:(對不起,我的家用電腦本地化爲法語...根異常是「服務器拒絕客戶證書「)
以下是完整的跟蹤:
System.ServiceModel.Security.SecurityNegotiationException: Le serveur a rejeté les informations d'identification du client. ---> System.Security.Authentication.InvalidCredentialException: Le serveur a rejeté les informations d'identification du client. ---> System.ComponentModel.Win32Exception: La tentative d’ouverture de session a échoué
--- Fin de la trace de la pile d'exception interne ---
à System.Net.Security.NegoState.ProcessReceivedBlob(Byte[] message, LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.StartReceiveBlob(LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.CheckCompletionBeforeNextSend(Byte[] message, LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.ProcessReceivedBlob(Byte[] message, LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.StartReceiveBlob(LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.CheckCompletionBeforeNextReceive(LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.StartSendBlob(Byte[] message, LazyAsyncResult lazyResult)
à System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
à System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
à System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
à System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
--- Fin de la trace de la pile d'exception interne ---
Server stack trace:
à System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
à System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUpgrade(Stream stream)
à System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
à System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
à System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
à System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
à System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
à System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
à System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
à System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
à System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
請注意,如果我直接從主機啓動客戶端,使用相同的客戶端配置文件,客戶端連接並完美通信!
這是當前已安裝的託管服務的服務器上的web.config文件:
<?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="ScgServiceLibrary.ScgBroadcastorService">
<endpoint binding="netTcpBinding" contract="ScgServiceLibrary.IScgBroadcastorService">
<identity>
<servicePrincipalName value="host/94.23.220.199" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
,這裏是我一直在外面和從主機使用客戶端配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IScgBroadcastorService">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://94.23.220.199/ScgBroadcastorService/Service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IScgBroadcastorService"
contract="ScgServiceLibrary.IScgBroadcastorService" name="NetTcpBinding_IScgBroadcastorService">
<identity>
<servicePrincipalName value="host/94.23.220.199" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
請注意,我已經加入了
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
線在web.c結束在服務器上創建onfig文件,以便在兩個wsdl鏈接上獲得具有IP地址的服務頁面。如果沒有這一行,這兩個鏈接將包含計算機名「ns304385」而不是IP地址,當然也不能從外部獲取wsdl。
謝謝你幫莫來解決剩餘的部署問題..我現在stucked,不知道怎樣做才能讓我的客戶,達到在網絡上託管我的WCF服務...
是否在IIS中的網站上激活** net.tcp **綁定(808:*)?很確定用於WPA的_Net.Tcp Listener Adapter_Windows系統也需要運行 – MickyD
我已經在IIS中託管的ScgBroadcastorService應用程序的高級設置中激活了net.tcp協議。你是這個意思嗎 ? –
是的,「net.tcp偵聽器適配器」服務正在運行。 –