「ステータスツール」を伴うWindowsサービスを書いています。サービスは、プロセス間通信用のWCF名前付きパイプエンドポイントをホストします。名前付きパイプを介して、ステータスツールは定期的にサービスに最新の「ステータス」を照会できます。
開発マシンには複数の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();
これは「権限」の問題だとは思いません-管理者権限でクライアントを実行しています-おそらくこれが壊れたドメイン固有の理由があるのでしょうか?
IPアドレスは、結局のところ、完全な赤いニシンでした。
例外の本当の理由は、WCFサービスによって返される無効な列挙値でした。
私の列挙型はこのように定義されました:
[DataContract]
public enum MyEnumValues : Byte
{
[EnumMember]
Enum1 = 0x10,
[EnumMember]
Enum2 = 0x20,
[EnumMember]
Enum3 = 0x30,
[EnumMember]
Enum4 = 0x40,
}
表面は綺麗に見えます。
ただし、基になるサービスによって報告された未加工のステータスはByte値が「0」であり、キャストするための対応するEnum値がありませんでした。
Enumの値がすべて有効であることを確認すると、ツールはクリスマスツリーのように点灯しました。
疑わしい場合は、WCFデータが無効であると想定してください。
この例外は、サーバー側にシリアル化の問題があることを意味します。
この問題は、トレースファイル(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>
私の場合、列挙型にない値をシリアル化していました。
同じ問題があったThere was an error reading from the pipe: Unrecognized error 109 (0x6d).
<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)
このエラーは、オブジェクトのポリモーフィック機能が原因で発生する場合があります。たとえば、次のサービスのメソッドは人のリストを返します:
[OperationContract]
List<Person> GetEmployee();
personクラスから継承されたスーパーバイザクラスがあり、上記のメソッドがスーパーバイザオブジェクトを返そうとした場合、WCFシリアライザクラスは応答を解釈できないため、このエラーが発生します。
この問題の解決策は、"既知のタイプ"または"サービスの既知のタイプ"を使用することです。暗黙のオブジェクトがメソッドまたはサービスを使用して相互作用するように指定する必要があります。私の例では、次のコードのように、ServiceKnownType属性をメソッドまたはサービスの宣言に配置できます。
[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();
これは、返されたペイロードが大きすぎるときにWCFサービスで発生しました。これをapp.configのserviceBehaviorに追加して修正しました。
<dataContractSerializer maxItemsInObjectGraph="[some big number]" />
多くのプロパティがあり、その中にセットはありません{}。これを追加することで私の問題は解決しました。
サービス操作がスローされ、チャネルに実際に障害が発生したときに、このエラーが発生しました。あなたのケースでは、サービス操作自体が正しく完了し、返却のみがスローされたことをすでに確認していますが、疑わしい場合は、サービス操作が正常に実行されることを確認してください。
古いチュートリアル を使用していて、プログラムで構成しようとしたため、この問題が発生しました。
私が欠けていた部分は、メタデータのエンドポイントを提供することでした( ありがとう、この投稿! )。
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"
);