我正在使用NetTcpBinding在客户端和服务器之间打开双工通信通道方面取得缓慢而稳定的进展。 (仅供参考,您可以观察我的新手进度here和here!)
我现在处于通过服务器防火墙成功连接到服务器的阶段,客户端可以向服务器发出请求。
然而,在另一个方向,事情并不那么开心。它在我自己的机器上测试时工作正常,但是当通过互联网进行测试时,当我尝试从服务器端发起回调时,我收到错误:
The message with Action 'http://MyWebService/IWebService/HelloWorld' cannot be
processed at the receiver,
due to a ContractFilter mismatch at the EndpointDispatcher.
This may be because of either a contract mismatch (mismatched Actions between
sender and receiver)
or a binding/security mismatch between the sender and the receiver.
Check that sender and receiver have the same contract and the same binding
(including security requirements, e.g. Message, Transport, None).
以下是代码的一些关键部分。首先,网络界面:
[ServiceContract(Namespace = "http://MyWebService", SessionMode = SessionMode.Required, CallbackContract = typeof(ISiteServiceExternal))]
public interface IWebService {
[OperationContract]
void Register(long customerID);
}
public interface ISiteServiceExternal {
[OperationContract]
string HelloWorld();
}
以下是IWebService的实现:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class WebService : IWebService {
void IWebService.Register(long customerID) {
Console.WriteLine("customer {0} registering", customerID);
var callbackService = OperationContext.Current.GetCallbackChannel<ISiteServiceExternal>();
RegisterClient(customerID, callbackService);
Console.WriteLine("customer {0} registered", customerID);
}
}
然后,在客户端(我在不知道自己在做什么的情况下摆弄这些属性):
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, Namespace="http://MyWebService")]
class SiteServer : IWebServiceCallback {
string IWebServiceCallback.HelloWorld() {
return "Hello World!";
}
...
}
那我在这里做错了什么?
编辑:添加app.config代码。来自服务器:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" logEntireMessage="true" maxMessagesToLog="1000" maxSizeOfMessageToLog="524288" />
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior name="mex">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name ="MyWebService.WebService" behaviorConfiguration="mex">
<endpoint address="net.tcp://localhost:8000" binding="netTcpBinding" contract="MyWebService.IWebService"
bindingConfiguration="TestBinding" name="MyEndPoint"></endpoint>
<endpoint address ="mex"
binding="mexTcpBinding"
name="MEX"
contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TestBinding" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" portSharingEnabled="false">
<readerQuotas maxDepth="32" maxStringContentLength ="8192" maxArrayLength ="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
并在客户端:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign">
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://mydomain.gotdns.com:8000/" binding="netTcpBinding"
bindingConfiguration="MyEndPoint" contract="IWebService" name="MyEndPoint" />
</client>
</system.serviceModel>
答案 0 :(得分:3)
感谢@Allon Guralnek,他帮助我注意到了什么问题:
在服务器端,我有:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class WebService : IWebService { ... }
在客户端,我有:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, Namespace="http://MyWebService")]
class SiteServer : IWebServiceCallback { ... }
冲突发生在PerCall
和PerSession
之间。我刚刚将服务器端改为PerSession
,而 - 休斯顿,我们已经升空了!
现在,为了让这项工作更加安全......请观看我的WCF学习曲线中的下一个令人兴奋的分期付款! :)
答案 1 :(得分:0)
您将回调合约列为ISiteServiceExternal
,但您的客户实施IWebServiceCallback
。先修复一下,看看你是否成功。