2009-03-31 32 views
9

Tôi đã gặp sự cố. Tôi là một chút mới tại WCF vì vậy bất kỳ trợ giúp sẽ được rất nhiều appreaciated.WCF: Net.TCP nhiều ràng buộc, cùng một cổng, Địa chỉ IP khác nhau

Dưới đây là mã của tôi:

public static void StartHosts() 
    { 
     try 
     { 
      // Create a new host 
      ServiceHost host = new ServiceHost(typeof(ServerTasks)); 

      List<IPAddress> ips = new List<IPAddress>(Dns.GetHostAddresses(Dns.GetHostName())); 
      if (IPAddress.Loopback != null) 
       ips.Add(IPAddress.Loopback); 

      ips.RemoveAll(i => i.AddressFamily != AddressFamily.InterNetwork); 

      foreach (var ip in ips) 
      { 
       string uri = string.Empty; 

       // Formulate the uri for this host 
       uri = string.Format(
        "net.tcp://{0}:{1}/ServerTasks", 
        ip.ToString(), 
        ServerSettings.Instance.TCPListeningPort 
       ); 


       // Add the endpoint binding 
       host.AddServiceEndpoint(
        typeof(ServerTasks), 
        new NetTcpBinding(SecurityMode.Transport) { TransferMode = TransferMode.Streamed }, 
        uri 
       ); 

      } 



      // Add the meta data publishing 
      var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 
      if (smb == null) 
       smb = new ServiceMetadataBehavior(); 

      smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 
      host.Description.Behaviors.Add(smb); 

      host.AddServiceEndpoint(
       ServiceMetadataBehavior.MexContractName, 
       MetadataExchangeBindings.CreateMexTcpBinding(), 
       "net.tcp://localhost/ServerTasks/mex" 
      ); 

      // Run the host 
      host.Open(); 
     } 
     catch (Exception exc) 
     { 
      DebugLogger.WriteException(exc); 
     } 
    } 

Một ngoại lệ được ném vào dòng: 'host.Open();'

Trường hợp ngoại lệ là:

System.InvalidOperationException Một đăng ký đã tồn tại cho URI 'net.tcp: //192.168.1.45: 4329/ServerTasks'.

Điều tôi đang cố gắng thực hiện là liên kết với tất cả các địa chỉ mạng trên máy để ứng dụng khách có thể tiếp cận dịch vụ từ bất kỳ mạng nào họ nhìn thấy trên đó. Khi tôi chạy mã này, nó tìm và cố gắng thiết lập một ràng buộc cho khoảng 5 IP khác nhau, bao gồm 127.0.0.1.

192.168.1.45 là IP thứ hai mà nó cố gắng liên kết. Tại thời điểm mà nó ném ngoại lệ tôi có thể thấy (sử dụng netstat) rằng chương trình đã ràng buộc với IP đầu tiên trong danh sách trên cổng 4329. Không có bất kỳ điều gì ràng buộc với cổng 4329 trên địa chỉ được đề cập trong ngoại lệ.

Rất tiếc, không có nhiều chi tiết, tôi muốn đưa ra một bài đăng súc tích. Nếu có ai cần thêm thông tin, tôi sẽ vui lòng cung cấp nó.

Lưu ý: Tôi đã thử đặt PortSharingEnabled thành true cho NetTcpBinding được tạo bên trong vòng lặp foreach, nhưng tôi vẫn gặp phải lỗi tương tự.

Bất kỳ trợ giúp hoặc tư vấn nào sẽ được đánh giá rất cao!

Cảm ơn

Trả lời

10

Cảm ơn thông tin Corazza!

Tôi đã tìm ra cách để thực hiện việc này. Tôi đã đi về điều này tất cả các cách sai.

Mục tiêu cuối cùng của tôi là có dịch vụ nghe trên mọi Địa chỉ IP có sẵn trên máy. Cố gắng liên kết với từng địa chỉ riêng lẻ là cách làm sai.

Thay vào đó, tôi chỉ cần liên kết dịch vụ với Tên máy chủ của máy (không phải 'localhost') và WCF tự động lắng nghe trên tất cả các bộ điều hợp.

Dưới đây là các mã điều chỉnh:

public static void StartHosts() 
    { 
     try 
     { 
      // Formulate the uri for this host 
      string uri = string.Format(
       "net.tcp://{0}:{1}/ServerTasks", 
       Dns.GetHostName(), 
       ServerSettings.Instance.TCPListeningPort 
      ); 

      // Create a new host 
      ServiceHost host = new ServiceHost(typeof(ServerTasks), new Uri(uri)); 

      // Add the endpoint binding 
      host.AddServiceEndpoint(
       typeof(ServerTasks), 
       new NetTcpBinding(SecurityMode.Transport) 
         { 
          TransferMode = TransferMode.Streamed 
         }, 
       uri 
      ); 

      // Add the meta data publishing 
      var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 
      if (smb == null) 
       smb = new ServiceMetadataBehavior(); 

      smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 
      host.Description.Behaviors.Add(smb); 

      host.AddServiceEndpoint(
       ServiceMetadataBehavior.MexContractName, 
       MetadataExchangeBindings.CreateMexTcpBinding(), 
       "net.tcp://localhost/ServerTasks/mex" 
      ); 

      // Run the host 
      host.Open(); 
     } 
     catch (Exception exc) 
     { 
      DebugLogger.WriteException(exc); 
     } 
    } 
+1

Ràng buộc với từng địa chỉ IP riêng là điều đúng để làm vì nếu không máy chủ của bạn có lỗ hổng bảo mật - tưởng tượng (không xảy ra) khi dịch vụ khác liên kết chính nó với địa chỉ IP máy chủ cụ thể và cùng một cổng trong khi dịch vụ của bạn bị ràng buộc với tất cả địa chỉ IP . Trong trường hợp này, imposter sẽ nhận được tất cả các yêu cầu kết nối từ các máy khách đến địa chỉ IP này. – AlexT

2

Mel,

Trong khi tôi chưa bao giờ cố gắng này trước khi bản thân mình, đây là một số mẫu để nhìn vào đó tôi đã nghe trước đó. Bạn có thể muốn tạo đối tượng liên kết của bạn trước và sau đó thêm cùng một thể hiện vào phương thức AddServiceEndpoint, chỉ là một ý nghĩ để bạn không tạo ra các ràng buộc mới mỗi khi tôi nhớ đọc ở đâu đó rằng netTCPBindings phải là mối quan hệ 1: 1 với địa chỉ (mặc dù bạn đang sử dụng các địa chỉ khác nhau).

Tôi không nghĩ bạn phải lo lắng về việc chia sẻ cổng khi bạn mở nhiều cổng.

Dưới đây là ví dụ về những gì bạn có thể muốn thực hiện với nhiều cổng.

http://www.aspfree.com/c/a/Windows-Scripting/WCF-and-Bindings/2/

ở đây là một mẫu tốt cho việc sử dụng portsharing trên NetTcpBinding.

http://blogs.msdn.com/drnick/archive/2006/08/08/690333.aspx

-Bryan

1

Hình như tôi hơi muộn :). Nhưng dù sao - có một cách khá đơn giản để làm cho Wcf lắng nghe tất cả các giao diện mạng có sẵn "net.tcp: //0.0.0.0: 8523/WCFTestService".

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