2013-04-05 19 views
13

Tôi đang viết một Dịch vụ Windows có kèm theo "công cụ trạng thái". Dịch vụ lưu trữ WCF có tên là điểm cuối đường ống cho giao tiếp giữa các quá trình. Thông qua đường ống có tên, công cụ trạng thái có thể truy vấn định kỳ dịch vụ cho "trạng thái" mới nhất.WCF NamedPipe CommunicationException - "Đường ống đã kết thúc. (109, 0x6d)."

enter image description here

Trên máy phát triển của mình, tôi có nhiều địa chỉ IP; một trong số đó là mạng "cục bộ" có địa chỉ 192.168.1.XX. Cái còn lại là mạng "công ty", với địa chỉ 10.0.X.XX. Dịch vụ Windows thu thập lưu lượng phát đa hướng UDP trên một địa chỉ IP duy nhất.

Dịch vụ Windows có, cho đến bây giờ, hoạt động tốt miễn là nó sử dụng địa chỉ "192.168.1.XX". Nó liên tục báo cáo trạng thái chính xác cho khách hàng.

Ngay sau khi tôi chuyển sang bên kia, "doanh nghiệp" Địa chỉ IP (10.0.X.XX) và khởi động lại dịch vụ, tôi nhận được liên tục "CommunicationExceptions" khi lấy tình trạng:

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

Bây giờ, Tôi sẽ không nghĩ rằng địa chỉ IP 'yêu cầu' của UDP Client nên có bất cứ điều gì để làm với các chức năng của giao diện Named-Pipe; chúng là những phần hoàn toàn riêng biệt của ứng dụng!

Sau đây là các WCF phần cấu hình có liên quan:

//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(); 

tôi sẽ không nghĩ rằng đây là một vấn đề 'quyền' - Tôi đang chạy client với quyền quản trị - nhưng có lẽ có một số lý do tên miền cụ thể điều này đã phá vỡ?

+0

Dấu vết ngăn xếp ngoại lệ trông như thế nào? Bạn có chắc chắn * không có gì khác thay đổi? Bạn đã khởi động lại Công cụ Trạng thái sau khi chuyển cấu hình dịch vụ chưa? Bạn có thể đăng một phần của mã công cụ trạng thái của bạn mà instantiates rpoxy của bạn và thực hiện cuộc gọi WCF? –

+0

Tôi sẽ cập nhật câu hỏi vào Thứ Hai, khi tôi trở lại làm việc.Một người bạn cũng cho rằng Địa chỉ IP có thể là một cá trích đỏ, và sự khác biệt thực sự có thể là giá trị trả về của các Enums cụ thể. Tôi cũng sẽ điều tra điều đó. – BTownTKD

Trả lời

9

Địa chỉ IP, hóa ra là một cá trích đỏ hoàn chỉnh.

Lý do thực sự cho ngoại lệ là không hợp lệ Giá trị enum được trả về bởi dịch vụ WCF.

enum của tôi được định nghĩa thusly:

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

Có vẻ tốt trên bề mặt.

Nhưng trạng thái thô được báo cáo bởi dịch vụ cơ bản là giá trị Byte là "0" và không có giá trị Enum tương ứng nào để truyền.

Khi tôi đảm bảo rằng các giá trị Enum đều hợp lệ, công cụ sáng lên như một cây thông Noel.

Khi nghi ngờ, giả sử dữ liệu WCF của bạn không hợp lệ.

+0

Có bất cứ điều gì trong các tập tin truy tìm trỏ đến điều này hoặc chúng tôi đang mắc kẹt với một lỗi "ống đã được kết thúc" chung chung và cần phải quét tất cả các mã liên quan đến hy vọng tìm thấy vấn đề serialization tiềm năng? –

+3

Tôi đã phải quét tất cả dữ liệu và xác minh thủ công dữ liệu đó. Tôi hy vọng bạn có may mắn hơn với dấu vết hữu ích! – BTownTKD

+0

"Khi nghi ngờ, giả sử dữ liệu WCF của bạn không hợp lệ." - đã lưu ngày của tôi :) – Yaniv

1

Tôi gặp lỗi này khi thao tác dịch vụ bị ném và kênh thực sự bị lỗi. Trong trường hợp của bạn, bạn đã xác minh rằng các hoạt động dịch vụ như vậy hoàn thành chính xác và chỉ trả lại ném, nhưng nếu có nghi ngờ, hãy chắc chắn rằng các hoạt động dịch vụ chạy OK.

2

Đã cùng một vấn đề There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • Một lý do là mâu thuẫn ràng buộc giữa client và server <netNamedPipeBinding> <security mode="None"></security>... (không giao tiếp)
  • Vấn đề không liên tục khác là time-out liên quan.

Cả hai đều có cùng thông báo lỗi hàng đầu.

Tăng thời gian hết thời gian trong máy chủ và sự cố ràng buộc khách hàng đã ngừng xuất hiện lại.

Ràng buộc thời gian ra đã được đặt quá thấp:

sendTimeout="00:00:05" receiveTimeout="00:00:05" 

Stack trace: 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)

1

Điều này xảy ra trong dịch vụ WCF của tôi khi payload trở quá lớn. Sửa lỗi bằng cách thêm vào trong serviceBehavior trong app.config:

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

Đôi khi lỗi này do tính năng đa hình của đối tượng gây ra. ví dụ sau đây phương pháp dịch vụ sẽ trở lại danh sách những người:

[OperationContract] 
List<Person> GetEmployee(); 

nếu chúng ta có Supervisor lớp kế thừa từ lớp Person, và các phương pháp trên cố gắng để trở Supervisor Object, lớp serializer WCF không thể giải thích phản ứng, vì vậy lỗi này sẽ được nâng lên.
Giải pháp cho vấn đề này là sử dụng "các loại đã biết" hoặc "loại dịch vụ đã biết". chúng ta phải xác định các đối tượng tiềm ẩn có thể tương tác bằng cách sử dụng phương thức hoặc dịch vụ. Ví dụ của tôi, chúng ta có thể đưa ServiceKnownType thuộc tính trong phương pháp hoặc khai dịch vụ như đoạn mã sau:

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

ngoại lệ này có nghĩa là có một vấn đề serialization trên phía máy chủ.

Sự cố này có thể được khắc phục bằng cách xem tệp theo dõi (svclog). Để bật truy tìm sử dụng cấu hình sau:

<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> 

Trong trường hợp của tôi, tôi đã sắp xếp một giá trị không có trong enum.

1

Tôi có nhiều thuộc tính không được đặt {} trong đó. Việc này đã giải quyết được vấn đề của tôi.

0

Vấn đề tương tự nhưng được giải quyết nhờ Wojciech 's answer.

tôi phải làm một chút tìm tòi thêm để tìm nơi để đặt tag <security> vì vậy đây là cách bắt đầu của phần System.ServiceModel trông bây giờ ...

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

Tôi có vấn đề này bởi vì tôi đang sử dụng một số older tutorial và cố gắng định cấu hình theo chương trình.

Phần tôi thiếu là cung cấp điểm cuối siêu dữ liệu (thank you, this post!).

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" 
); 
Các vấn đề liên quan