2009-09-25 27 views
5

Vì vậy, tôi có một ứng dụng có sẵn một API .NET. Thư viện API của họ giao tiếp với ứng dụng chính của họ thông qua các cuộc gọi từ xa .NET. Để sử dụng API, ứng dụng phải được thiết lập và đang chạy.Làm cách nào để biết ứng dụng khác đã đăng ký kênh IPC Remoting?

Vì vậy, tôi có một trường hợp mà tôi cần phải bắt đầu lập trình ứng dụng và sau đó khởi tạo một trong các đối tượng API, mà cố gắng mở một kênh từ xa IPC đến ứng dụng chính. Vấn đề là, sau khi tôi bắt đầu quá trình, có một vài giây giữa khởi động và khi ứng dụng đăng ký kênh. Nếu tôi cố gắng khởi tạo một đối tượng API trước khi kênh được đăng ký, nó sẽ thoát ra ngoài.

Nó không giúp tôi biết rất ít về .NET remoting.

Làm cách nào để xác định từ ứng dụng MY sử dụng API của họ nếu ứng dụng THEIR đã đăng ký kênh để liên lạc nên tôi biết có thể khởi tạo đối tượng API của họ không?

+0

Jon Skeet! Bạn phải biết câu trả lời! = [ – snicker

Trả lời

2

Hãy thử điều này:

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
     IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
     IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
     if (activeListeners.Any(conn => conn.Port == port)) 
     { 
      return true; 
     } 
     return false; 
} 

đèo tại cảng và bạn sẽ nhận được một giá trị chỉ ra liệu có một người biết lắng nghe trên đó port.Hope này giúp

+1

Vấn đề là .. nó không phải là một cổng. Đó là IPC remoting, do đó, có cổng "tên" nhưng không thực tế cổng. – snicker

+0

Nếu bạn đang tạo lập trình một quá trình lắng nghe các kết nối thì nó phải lắng nghe trên một số cổng. Ví dụ MSDN này có máy chủ lắng nghe các cuộc gọi IPC trên cổng 9090: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx Nếu bạn không ' t biết cổng, hãy thử chạy netstat từ dòng commannd, bạn sẽ có thể xem những gì đang sử dụng cổng –

+0

Ah, có vẻ như có ý nghĩa. Tuy nhiên, cổng thay đổi ngẫu nhiên. Bất kỳ đề xuất cho điều đó? – snicker

0

Chỉ cần để có được ra khỏi hộp cho một thời điểm, bạn có nghĩ về việc sử dụng WCF với MSMQ không? Tôi không chắc rằng tôi hoàn toàn hiểu bạn là kiến ​​trúc, nhưng có vẻ như khách hàng của API phải quay lên một quy trình khác lưu trữ API. Có thể có sự cố thời gian giữa thời điểm bạn bắt đầu máy chủ API và khi khách hàng cố thực hiện cuộc gọi. Microsoft gần đây đã từ chối .NET Remoting (cũng như tất cả các công nghệ truyền thông trước đây của họ như các dịch vụ web ASMX) như là di sản, và rất khuyến khích các nhà phát triển chuyển sang nền tảng WCF.

Nếu bạn sử dụng WCF với MSMQ, bạn không nên gặp sự cố về thời gian. Ứng dụng khách của bạn có thể thả tin nhắn trong một hàng đợi lâu bất kể máy chủ API có đang chạy hay không. Các máy chủ API có thể được bắt đầu bất cứ lúc nào, và nó sẽ nhận và xử lý bất kỳ tin nhắn chờ đợi trong hàng đợi. Ngay cả khi bạn vẫn còn ứng dụng máy khách khởi động máy chủ API, vấn đề về thời gian sẽ không còn là vấn đề bởi vì bạn đang sử dụng xếp hàng để chuyển các thư thay vì .NET Remoting. WCF cung cấp một wrapper đẹp, thuận tiện, dễ sử dụng xung quanh MSMQ, vì vậy rào cản để vào là tương đối thấp.

Điều tuyệt vời khác khi sử dụng WCF trên .NET Remoting là bạn có thể dễ dàng di chuyển máy chủ API đến một máy chủ vật lý khác mà không phải thay đổi (các) ứng dụng khách. Bạn thậm chí có thể chuyển sang một nền tảng xếp hàng khác nếu bạn muốn (chẳng hạn như RabbitMQ trên AMQP), mà không thay đổi ứng dụng máy khách hoặc API. WCF xử lý tất cả các tương tác đó cho bạn, cung cấp một sự tách biệt sạch hơn và truyền thông đáng tin cậy hơn giữa ứng dụng khách và máy chủ API của bạn.

Nếu di chuyển đến WCF không phải là một tùy chọn, bạn có thể đặt cổng rõ ràng bằng .NET Remoting. Tôi không chắc chắn làm thế nào bạn đang cấu hình máy chủ API của bạn, nhưng URL cho bất kỳ đối tượng truy cập từ xa được thường là dưới hình thức:

tcp://<hostname>[:<port>]/<object> 

Nếu bạn thêm các cổng, sau đó bạn sẽ có thể sử dụng giải pháp Abhijeet để xác định xem cổng có mở hay không. Bạn sẽ không nhận được sự kết nối lỏng lẻo và các lợi ích truyền thông đáng tin cậy của WCF, nhưng nó chắc chắn sẽ ít hoạt động hơn. ;)

+0

WCF không phải là một lựa chọn. Tôi không kiểm soát nguồn của máy chủ. Có một ứng dụng nguồn đóng được viết bằng một ngôn ngữ không được quản lý (có thể là C++) và một API được cung cấp dưới dạng một thư viện .NET. Thư viện là những gì tạo ra các đối tượng truy cập từ xa. Tôi phải sử dụng từ xa mặc dù tôi biết nó không được chấp nhận và hút. – snicker

0

Bạn đã xem xét việc gói nỗ lực để khởi tạo đối tượng API thành một khối try-catch chưa? Sau đó, bạn có thể phân tích ngoại lệ và xem liệu nó có phải do máy chủ không nghe hay không. Và nếu nó được, bạn chỉ có thể chờ đợi và thử lại.

Làm cho tinh thần?

+0

Có, nhưng tiếc là API nguồn đã đóng được viết kém và đặt một số biến tĩnh ngăn không cho nó được khởi tạo lại trong cùng một thời gian chạy mà không sử dụng tấn phản xạ để sửa nó. Nó sẽ là một giải pháp khó chịu. – snicker

+0

Làm điều đó trong một AppDomain khác sau đó? –

+0

Tôi đã thử gói myObj = Activator.GetObject (...) trong một khối try-catch, thử nghiệm cho null, vv Nó không hoạt động vì nó trả về một đối tượng _TransparentProxy cho dù máy chủ có đang hoạt động hay không. Nó không phải cho đến sau khi bạn cố gắng sử dụng myObj mà bạn nghiêng. Abjiheet có câu trả lời đúng, theo ý kiến ​​của tôi. – IAbstract

0

Chỉ một lỗi đánh máy nhỏ trong mã. Correction là như sau:

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
    IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
    IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
    if (activeListeners.Any(conn => conn.Port == port)) 
    { 
     return true; 
    } 
    return false; 
} 
0

Khi bạn đăng ký một IpcServerChannel nó làm cho một ống đặt tên để giao tiếp trên với tên của tên Cảng bạn đã chọn cho IpcServerChannel của bạn. Bạn có thể xem danh sách các Ống có tên để xem Tên cổng của bạn có ở đó không.

System.IO.Directory.GetFiles(@"\\.\pipe\").Any((path) => path.Contains(@"\\.\pipe\" + pipeName)); 
Các vấn đề liên quan