8

過去 2 日間、WCF を使用して作業を行ってきましたが、開発マシンのサーバーとクライアントの両方で非常にうまく機能していました。ネットワーク上の別のマシンでクライアントを使用して分散テストを実行しようとしているので、問題が発生し始めました。現在、私が得ているエラーは次のとおりです。

アクション ' http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames 'を含むメッセージは、EndpointDispatcher での ContractFilter の不一致により、受信側で処理できません。これは、コントラクトの不一致 (送信者と受信者の間のアクションの不一致) または送信者と受信者の間のバインディング/セキュリティの不一致が原因である可能性があります。送信者と受信者が同じコントラクトと同じバインド (メッセージ、トランスポート、なしなどのセキュリティ要件を含む) を持っていることを確認します。

これはすでに大規模な学習経験であるため (これまでにリモート処理や 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);
}

私が行ったバインディングとコントラクトのセットアップはそれらを同一にするはずであり、この問題は発生しないはずです(そしてセキュリティをオフにする必要があります)。今どこに行けばいいのかわからない。

4

1 に答える 1

10

私はあなたに同意します - サーバーとクライアントの両方のセキュリティ設定は同一のようです。

補足: 実行したら:

binding.Security.Mode = SecurityMode.None;

「binding.Security」オブジェクト以下にこれ以上設定を指定する必要はないと思います。その後の余分な行は必要ありません。

私の目を引いたのは、あなたのサービス契約です:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)]
public interface IWindowUpdateContract 
{
    [OperationContract]
    void UpdateWindowFrames(WindowFrame frame);
    [OperationContract]
    void WindowHasClosed(IntPtr hwnd);
}

これらの操作は何も返さない - これは珍しいことです。WCF サービスの既定の動作は、要求/応答です。要求を送信して応答を返します。

それらに何か (ステータスなど、文字列、int など) を返すようにするか、WCF が何も期待しないことを認識できるように、それらを「一方向」呼び出しとしてマークする必要があります。

[ServiceContract(ProtectionLevel = ProtectionLevel.None)]
public interface IWindowUpdateContract 
{
    [OperationContract(IsOneWay=true)]
    void UpdateWindowFrames(WindowFrame frame);
    [OperationContract(IsOneWay=true)]
    void WindowHasClosed(IntPtr hwnd);
}

マルク

于 2009-11-12T18:07:11.810 に答える