web-dev-qa-db-ja.com

WCF NamedPipe CommunicationException-「パイプが終了しました。(109、0x6d)」

「ステータスツール」を伴うWindowsサービスを書いています。サービスは、プロセス間通信用のWCF名前付きパイプエンドポイントをホストします。名前付きパイプを介して、ステータスツールは定期的にサービスに最新の「ステータス」を照会できます。

enter image description here

開発マシンには複数のIPアドレスがあります。それらの1つは、192.168.1.XXアドレスを持つ「ローカル」ネットワークです。もう1つは、10.0.X.XXアドレスを持つ「企業」ネットワークです。 Windowsサービスは、単一のIPアドレスでUDPマルチキャストトラフィックを収集します。

Windowsサービスは、これまで「192.168.1.XX」アドレスを使用する限り、正常に機能していました。それは常にクライアントにステータスを正しく報告します。

他の「企業」IPアドレス(10.0.X.XX)に切り替えてサービスを再起動するとすぐに、ステータスを取得するときに「CommunicationExceptions」が継続的に発生します。

"There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)."

さて、UDPクライアントの「要求された」IPアドレスがNamed-Pipeインターフェースの機能と関係があるとは思いません。それらはアプリケーションの完全に別の部分です!

関連するWCF構成セクションは次のとおりです。

//On the Client app:
string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe";
ChannelFactory<IMyService> proxyFactory =
    new ChannelFactory<IMyService>(
        new NetNamedPipeBinding(),
        new EndpointAddress(myNamedPipe));


//On the Windows Service:
string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe";
myService = new MyService(myCustomArgs);
serviceContractHost = new ServiceHost(myService );
serviceContractHost.AddServiceEndpoint(
    typeof(IMyService),
    new NetNamedPipeBinding(),
    myNamedPipe);

serviceContractHost.Open();

これは「権限」の問題だとは思いません-管理者権限でクライアントを実行しています-おそらくこれが壊れたドメイン固有の理由があるのでしょうか?

16
BTownTKD

IPアドレスは、結局のところ、完全な赤いニシンでした。

例外の本当の理由は、WCFサービスによって返される無効な列挙値でした。

私の列挙型はこのように定義されました:

[DataContract]
public enum MyEnumValues : Byte
{
    [EnumMember]
    Enum1 = 0x10,
    [EnumMember]
    Enum2 = 0x20,
    [EnumMember]
    Enum3 = 0x30,
    [EnumMember]
    Enum4 = 0x40,
} 

表面は綺麗に見えます。

ただし、基になるサービスによって報告された未加工のステータスはByte値が「0」であり、キャストするための対応するEnum値がありませんでした。

Enumの値がすべて有効であることを確認すると、ツールはクリスマスツリーのように点灯しました。

疑わしい場合は、WCFデータが無効であると想定してください。

13
BTownTKD

この例外は、サーバー側にシリアル化の問題があることを意味します。

この問題は、トレースファイル(svclog)を調べることで解決できます。トレースをオンにするには、次の構成を使用します。

<system.diagnostics>
        <sources>
            <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="false">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Remos\Log\WcfTraceServer.svclog" />
        </sharedListeners>
    </system.diagnostics>

私の場合、列挙型にない値をシリアル化していました。

5
Martin Staufcik

同じ問題があったThere was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • 1つの理由は、クライアントとサーバー間で一貫性のないバインディングでした_<netNamedPipeBinding> <security mode="None"></security>..._(通信なし)
  • 他の断続的な問題は、タイムアウトに関連したものでした。

どちらにも同じトップエラーメッセージがありました。

サーバーとクライアントのバインディングでtime outを増やすと、問題の再現が停止しました。

設定が低すぎるバインドのタイムアウト:

_sendTimeout="00:00:05" receiveTimeout="00:00:05"
_

スタックトレース:at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) at System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout) at System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(iMessage message)

3
Wojciech

このエラーは、オブジェクトのポリモーフィック機能が原因で発生する場合があります。たとえば、次のサービスのメソッドは人のリストを返します:

[OperationContract]
 List<Person> GetEmployee();

personクラスから継承されたスーパーバイザクラスがあり、上記のメソッドがスーパーバイザオブジェクトを返そうとした場合、WCFシリアライザクラスは応答を解釈できないため、このエラーが発生します
この問題の解決策は、"既知のタイプ"または"サービスの既知のタイプ"を使用することです。暗黙のオブジェクトがメソッドまたはサービスを使用して相互作用するように指定する必要があります。私の例では、次のコードのように、ServiceKnownType属性をメソッドまたはサービスの宣言に配置できます。

[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();
3
AAAA

これは、返されたペイロードが大きすぎるときにWCFサービスで発生しました。これをapp.configのserviceBehaviorに追加して修正しました。

<dataContractSerializer maxItemsInObjectGraph="[some big number]" />
2
pizza247

多くのプロパティがあり、その中にセットはありません{}。これを追加することで私の問題は解決しました。

1
Rahbek

サービス操作がスローされ、チャネルに実際に障害が発生したときに、このエラーが発生しました。あなたのケースでは、サービス操作自体が正しく完了し、返却のみがスローされたことをすでに確認していますが、疑わしい場合は、サービス操作が正常に実行されることを確認してください。

1
J S

古いチュートリアル を使用していて、プログラムで構成しようとしたため、この問題が発生しました。

私が欠けていた部分は、メタデータのエンドポイントを提供することでした( ありがとう、この投稿! )。

ServiceMetadataBehavior serviceMetadataBehavior = 
    Host.Description.Behaviors.Find<ServiceMetadataBehavior>();

if (serviceMetadataBehavior == null)
{
    serviceMetadataBehavior = new ServiceMetadataBehavior();
    Host.Description.Behaviors.Add(serviceMetadataBehavior);
}

Host.AddServiceEndpoint(
    typeof(IMetadataExchange), 
    MetadataExchangeBindings.CreateMexNamedPipeBinding(), 
    "net.pipe://localhost/PipeReverse/mex"
);
0
Ben

同じ問題ですが、 Wojciechanswer のおかげで解決しました。

<security>タグを配置する場所を見つけるために、もう少し掘り下げる必要があったので、system.serviceModelセクションの先頭は次のようになります...

<system.serviceModel>
   <bindings>
     <netNamedPipeBinding>
       <binding>
         <security mode="None"></security>
       </binding>
     </netNamedPipeBinding>
   </bindings>
   ....
0