过去两天我一直在使用 WCF,并且在我的开发机器上的服务器和客户端都运行良好。现在我正在尝试在网络上的另一台机器上对客户端进行一些分布式测试,我开始遇到问题。现在我得到的错误是:
由于 EndpointDispatcher 的 ContractFilter 不匹配,接收方无法处理带有 Action ' http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames ' 的消息。这可能是因为合约不匹配(发送方和接收方之间的操作不匹配)或发送方和接收方之间的绑定/安全不匹配。检查发送方和接收方是否具有相同的合同和相同的绑定(包括安全要求,例如消息、传输、无)。
由于这已经是一个巨大的学习经验(我之前没有做过任何远程处理、RPC 等)我想继续开发学习工具并在我完成后重新审视安全性(我无意构建任何实际上会在没有适当的安全最佳实践的情况下使用)。
笔记:
- 我没有为 WCF 设置配置文件 - 我正在以编程方式进行所有操作。
- 我的网络不是域的一部分,因此默认安全设置对我不起作用(使用 net.tcp)。
- 我正在使用“.Net 3.5”。
我的服务器是这样创建的:
var svh = new ServiceHost(_serviceImplementation);
var binding = new NetTcpBinding();
binding.ReaderQuotas.MaxArrayLength = 2000000;
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
svh.AddServiceEndpoint(_serviceInterface, binding, string.Format("net.tcp://{0}:{1}", _endPoint.Address, _endPoint.Port));
_stopFlag = new AutoResetEvent(false);
svh.Open();
_stopFlag.WaitOne();
我的客户是这样创建的:
var binding = new NetTcpBinding();
binding.ReaderQuotas.MaxArrayLength = 2000000;
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
var scf = new ChannelFactory<IUserInputContract>(binding, "net.tcp://192.168.0.42:8001");
_uiUpdateServer = scf.CreateChannel();
我的合同(只是在作为对客户端和服务器的引用添加的类库中)是:
[ServiceContract(ProtectionLevel = ProtectionLevel.None)]
public interface IWindowUpdateContract {
[OperationContract]
void UpdateWindowFrames(WindowFrame frame);
[OperationContract]
void WindowHasClosed(IntPtr hwnd);
}
我觉得我所做的绑定和合同设置应该使它们相同并且我不应该有这个问题(并且应该关闭安全性)。我只是不知道现在该去哪里。