2010-08-09 47 views
16

Nguyên:Kết nối ổ cắm đã bị hủy bỏ - CommunicationException

  • Tôi nghĩ đây là một vấn đề tham chiếu vòng tròn ........ hóa ra nó không phải.
  • Sự cố phát sinh từ việc chưa cấu hình cấu hình dịch vụ.
  • Vì các giá trị mặc định rất thấp, việc gửi nhiều dữ liệu sẽ làm cho dịch vụ bị sụp đổ.

Kịch bản:

  • Dường như tôi có thể tham khảo thông tư phục vụ WCF của tôi, nhưng sử dụng "[DataContract (IsReference = true)]", không làm gì để giúp sửa chữa nó.
  • Tôi nhận được lỗi "Kết nối socket đã bị hủy bỏ. Điều này có thể do lỗi xử lý tin nhắn của bạn hoặc thời gian chờ nhận được vượt quá bởi máy chủ từ xa hoặc sự cố tài nguyên mạng cơ bản. : 00 '. "
  • Tôi đã bỏ lỡ điều gì chưa?

Code:

[DataContract(IsReference=true)] 
public class Message 
{ 
    [DataMember] 
    public string TopicName { get; set; } 

    [DataMember] 
    public string EventData { get; set; } 

    [DataMember] 
    public SerializableDictionary<string, FuturesLineAsset> FuturesLineDictionary { get; set ; } 
} 

Suy nghĩ:

  • Tôi tự hỏi nếu đó là vì tôi có một FuturesAsset lớp, mà có một loại tài sản của BindableDictionary (ĐÂY LÀ MỘT CUSTOM OBJECT) và thuộc tính đó chứa danh sách FuturesLinesAssets.
  • Xem dưới đây:

phụ huynh:

public class FuturesAsset 
{ 
    public string AssetName { get; set; } 
    public BindableDictionary<string, FuturesLineAsset> AssetLines { get; private set; } 

    public FuturesAsset() 
    { 
     AssetLines = new BindableDictionary<string, FuturesLineAsset>(); 
    } 

    public FuturesAsset(string assetName) 
    { 
     AssetLines = new BindableDictionary<string, FuturesLineAsset>(); 
     AssetName = assetName; 
    } 
} 

Child:

public class FuturesLineAsset 
{ 

    public string ReferenceAsset { get; set; } 
    public string MID { get; set; } 
    public double LivePrice { get; set; } 
    public DateTime UpdateTime { get; set; } 
    public DateTime LastContributedTime { get; set; } 
    public double Spread { get; set; } 
    public double Correlation { get; set; } 
    public DateTime Maturity { get; set; } 
    public double ReferenceCurve { get; set; } 

    public FuturesLineAsset(string mID, string referenceAsset, double livePrice) 
    { 
     MID = mID; 
     ReferenceAsset = referenceAsset; 
     ReutersLivePrice = livePrice; 
    } 
} 
+0

Làm thế nào để bạn nhận được từ 'Lỗi socket' với tham chiếu vòng tròn? Bạn có bất kỳ thông báo lỗi nào bạn có thể thêm vào bài đăng không? –

+0

Bởi vì khi tôi googled thông báo lỗi tôi nhận được rất nhiều kết quả nói về tham chiếu vòng tròn. Ngoài ra, lỗi chỉ xảy ra khi tôi thử và gửi ALOT dữ liệu, nếu không nó hoạt động tốt. – Goober

Trả lời

11

ngoại lệ mà không liên quan đến Thông tư tham khảo, nó chỉ thuần túy thời gian ra như bạn cố gắng bơm tấn dữ liệu qua dây.

Giá trị mặc định đi kèm với WCF rất thấp (những thay đổi này đã được thay đổi trong WCF 4 mà tôi tin). Have a đọc trên hai bài đăng trên blog, họ nên cung cấp cho bạn một ý tưởng về cách dethrottle dịch vụ của bạn:

Creating high performance WCF services

How to throttle a Wcf service, help prevent DoS attacks, and maintain Wcf scalability

Cập nhật: cũng có một số timeout khác nhau trong cấu hình WCF và tùy thuộc vào khách hàng hay máy chủ bạn đang nói về bạn cần phải cập nhật một mệnh đề thời gian chờ khác ... có đọc thread về ý nghĩa của từng người và bạn có thể tìm ra cái nào bạn cần để tăng lên. Hoặc, bạn chỉ có thể đặt mọi thời gian chờ thành int.max nếu bạn không thực sự quan tâm nếu cuộc gọi có thể mất nhiều thời gian để hoàn thành.

+0

FANTASTIC BẠN ĐÃ ĐÚNG NGƯỜI TÔI TỐT! – Goober

+0

Chết tiệt, liên kết thứ 2 đã chết. – Gallen

+0

Có gương cho liên kết thứ hai không? – CodeSlinger512

13

Lỗi này có thể do một số thứ gây ra. Trong khi đó là vấn đề về thời gian trong trường hợp này, nó thường không liên quan gì tới thời gian, đặc biệt nếu lỗi được nhận ngay lập tức. Lý do có thể là:

  • Các đối tượng được sử dụng làm tham số hoặc kiểu trả về trong hợp đồng của bạn không có thuộc tính DataContract và không được trang trí với thuộc tính DataContract. Kiểm tra các lớp được sử dụng làm tham số hoặc kiểu trả về, nhưng cũng tất cả các loại được sử dụng bởi các thuộc tính công khai của các lớp đó. Nếu bạn thực hiện một hàm tạo với các tham số cho một trong các lớp đó, trình biên dịch sẽ không thêm hàm tạo parameterless mặc định cho bạn nữa, do đó bạn sẽ cần thêm chính nó.
  • Giới hạn mặc định được xác định trong cấu hình dịch vụ quá thấp (MaxItemsInObjectGraph, MaxReceivedMessageSize, MaxBufferPoolSize, MaxBufferSize, MaxArrayLength).
  • Một số thuộc tính công khai của đối tượng DataContract của bạn là chỉ đọc. Đảm bảo tất cả các thuộc tính công khai đều có cả getters và setters.
+0

Tôi đã gặp lỗi này với đối tượng trả về chứa các thuộc tính có số thập phân nằm ngoài ranh giới và enums có giá trị không hợp lệ. – pauloya

+1

Chuyển một 'DataTable' thông qua không có' .TableName', hoặc một bảng trống không có dữ liệu ('new DataTable()') cũng có thể gây ra điều này. –

+2

Tôi gặp lỗi này và nguyên nhân gốc là WCF. Khi tôi chuyển sang WCF, vấn đề đã biến mất. – pettys

2

Đã xảy ra sự cố này với quy trình intialisation dài đã được gọi từ sự kiện OnStart của trình cài đặt Máy chủ lưu trữ Windows. Cố định bằng cách đặt chế độ bảo mật và thời gian chờ cho ràng buộc TCP.

  // Create a channel factory. 
      NetTcpBinding b = new NetTcpBinding(); 
      b.Security.Mode = SecurityMode.Transport; 
      b.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows; 
      b.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign; 

      b.MaxReceivedMessageSize = 1000000; 
      b.OpenTimeout = TimeSpan.FromMinutes(2); 
      b.SendTimeout = TimeSpan.FromMinutes(2); 
      b.ReceiveTimeout = TimeSpan.FromMinutes(10); 
0

Các lỗi WCF:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was ...

nơi timeouts báo cáo là rất gần với 1 phút (ví dụ 00:00:59.9680000) hoặc 1 phút chính xác (ví dụ 00:01:00) có thể được gây ra bởi thông điệp quá lớn và exceeding the settings for the binding .

này có thể được cố định bằng cách tăng giá trị trong tập tin cấu hình, ví dụ .:

<binding name="MyWcfBinding" 
     maxReceivedMessageSize="10000000" 
     maxBufferSize="10000000" 
     maxBufferPoolSize="10000000" /> 

(ví dụ giá trị duy nhất, bạn có thể muốn điều chỉnh chúng).

1

Trường hợp ngoại lệ này xảy ra đối với tôi khi tôi trả lại một đối tượng có bộ sưu tập IEnumerable trong đó và một ngoại lệ đã xảy ra khi một trong các thành viên thu thập được truy xuất. Tại thời điểm đó, đã quá muộn để nắm bắt nó trong mã của bạn, và có lẽ WCF được thiết kế để ngắt kết nối socket trong trường hợp đó bởi vì nó cũng đã quá muộn để báo cáo một ngoại lệ cho máy khách, vì nó đã bắt đầu kết quả truyền trực tuyến.

0

Sự cố này cũng có thể do không dọn dẹp máy khách WCF khi bạn đã sử dụng xong. Trong hệ thống của chúng tôi, chúng tôi sử dụng mẫu dùng một lần cùng với gói tất cả các cuộc gọi hàm vào hệ thống để cho phép dọn dẹp và ghi nhật ký hợp lý. Chúng tôi sử dụng một phiên bản của lớp sau:

public class WcfWrapper : IDisposable 
    { 
     private readonly OperationContextScope _operationContextScope; 
     private readonly IClientChannel _clientChannel; 

     public WcfWrapper(IClientChannel clientChannel) 
     { 
      _clientChannel = clientChannel; 
      _operationContextScope = new OperationContextScope(_clientChannel); 
     } 



     public void Dispose() 
     { 
      _operationContextScope.Dispose(); 
     } 


     public T Function<T>(Func<T> func) 
     { 
      try 
      { 
       var result = func(); 
       _clientChannel.Close(); 
       return result; 
      } 
      catch (Exception ex) 
      { 
       KTrace.Error(ex); 
       _clientChannel.Abort(); 
       throw; 
      } 

     } 

     public void Procedure(Action action) 
     { 
      try 
      { 
       action(); 
       _clientChannel.Close(); 
      } 
      catch (Exception ex) 
      { 
       KTrace.Error(ex); 
       _clientChannel.Abort(); 
       throw; 
      } 
     } 
    } 

} 

Mỗi WCF gọi chúng ta thực hiện vào dịch vụ của chúng tôi là thông qua một lớp giao diện được định nghĩa như một sau:

public sealed class WcfLoginManager : ILoginManager 
    { 
     private static LoginManagerClient GetWcfClient() 
     { 
      return 
       new LoginManagerClient(
        WcfBindingHelper.GetBinding(), 
        WcfBindingHelper.GetEndpointAddress(ServiceUrls.LoginManagerUri)); 

     } 

     public LoginResponse Login(LoginRequest request) 
     { 
      using(var loginManagerClient = GetWcfClient()) 
      using (var slice = new WcfWrapper(loginManagerClient.InnerChannel)) 
      { 
       DSTicket ticket; 
       DSAccount account; 
       return slice.Function(() => new LoginResponse(loginManagerClient.Login(request.accountName, request.credentials, out ticket, out account), ticket, account)); 
      } 
     } 
    } 

Sử dụng mô hình này, tất cả các WCF gọi vào hệ thống được bao bọc bằng chức năng hoặc phương thức thủ tục, cho phép đầu tiên đảm bảo ghi nhật ký xảy ra trên tất cả các lỗi và thứ hai để đảm bảo kênh bị đóng khi không có lỗi xảy ra nhưng bị hủy nếu có ngoại lệ xảy ra. Cuối cùng, vì nó trong một tuyên bố sử dụng, việc xử lý cuối cùng của kênh được gọi. Bằng cách này, các lỗi xảy ra do các kênh không được dọn dẹp đúng cách, sẽ trông giống như lỗi này, sẽ bị ngăn chặn.

Các vấn đề liên quan