2010-03-30 38 views
19

Tôi không thể sử dụng kênh không an toàn sau khi kênh an toàn đã được đăng ký. Mã bên dưới chỉ hoạt động nếu ở phía máy khách, kênh không an toàn được đăng ký trước đó.Trộn các kênh an toàn & không an toàn

Có thể kết hợp các kênh an toàn và không an toàn mà không có bất kỳ ràng buộc nào đối với đơn đặt hàng đăng ký không?

using System; 
using System.Collections; 
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Channels; 
using System.Runtime.Remoting.Channels.Tcp; 

public class SampleObject : MarshalByRefObject 
{ 
    public DateTime GetTest() { return DateTime.Now; } 
} 
public class SampleObject2 : MarshalByRefObject 
{ 
    public DateTime GetTest2() { return DateTime.Now; } 
} 
static class ProgramClient 
{ 
    private static TcpClientChannel RegisterChannel(bool secure, string name, int priority) 
    { 
     IDictionary properties = new Hashtable(); 
     properties.Add("secure", secure); 
     properties.Add("name", name); 
     properties.Add("priority", priority); 
     var clientChannel = new TcpClientChannel(properties, null); 
     ChannelServices.RegisterChannel(clientChannel, false); 
     return clientChannel; 
    } 
    private static void Secure() 
    { 
     RegisterChannel(true, "clientSecure", 2); 
     var testSecure = (SampleObject2)Activator.GetObject(typeof(SampleObject2), "tcp://127.0.0.1:8081/Secured.rem"); 
     Console.WriteLine("secure: " + testSecure.GetTest2().ToLongTimeString()); 
    } 
    private static void Unsecure() 
    { 
     RegisterChannel(false, "clientUnsecure", 1); 
     var test = (SampleObject)Activator.GetObject(typeof(SampleObject), "tcp://127.0.0.1:8080/Unsecured.rem"); 
     Console.WriteLine("unsecure: " + test.GetTest().ToLongTimeString()); 
    } 
    internal static void MainClient() 
    { 
     Console.Write("Press Enter to start."); 
     Console.ReadLine(); 
     // Works only in this order 
     Unsecure(); 
     Secure(); 
     Console.WriteLine("Press ENTER to end"); 
     Console.ReadLine(); 
    } 
} 
static class ProgramServer 
{ 
    private static TcpServerChannel RegisterChannel(int port, bool secure, string name) 
    { 
     IDictionary properties = new Hashtable(); 
     properties.Add("port", port); 
     properties.Add("secure", secure); 
     properties.Add("name", name); 
     //properties.Add("impersonate", false); 
     var serverChannel = new TcpServerChannel(properties, null); 
     ChannelServices.RegisterChannel(serverChannel, secure); 
     return serverChannel; 
    } 
    private static void StartUnsecure() 
    { 
     RegisterChannel(8080, false, "unsecure"); 
     RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "Unsecured.rem", WellKnownObjectMode.Singleton); 
    } 
    private static void StartSecure() 
    { 
     RegisterChannel(8081, true, "secure"); 
     RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject2), "Secured.rem", WellKnownObjectMode.Singleton); 
    } 
    internal static void MainServer() 
    { 
     StartUnsecure(); 
     StartSecure(); 
     Console.WriteLine("Unsecure: 8080\n Secure: 8081"); 
     Console.WriteLine("Press the enter key to exit..."); 
     Console.ReadLine(); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     if (args.Length == 1 && args[0] == "server") 
      ProgramServer.MainServer(); 
     else 
      ProgramClient.MainClient(); 
    } 
} 

Chỉnh sửa: Không thay đổi với .NET 4 và VS 2010.

+3

Bạn nói rằng "không hoạt động"; bạn có thể làm rõ nó đang làm gì không? –

+0

@ M.Babcock Cảm nhận của bạn là một câu hỏi rất cũ, để sử dụng những người đã không được trong một vài tháng. Chỉ cần fyi –

+0

Tôi biết đó là một câu hỏi khá cũ nhưng nhận thấy nó vẫn còn có liên quan kể từ khi người kiểm duyệt đã không tắt nó được nêu ra. Vui lòng xóa câu trả lời của tôi nếu bạn cảm thấy không cần thiết. –

Trả lời

1

này được câu hỏi cổ điển thú vị, tôi đã dành khoảng một tuần cố gắng giải quyết vấn đề này, và phải thực hiện một công việc xung quanh. Nhưng đây là những gì tôi đã khám phá ra: câu trả lời rất có thể là: KHÔNG, BẠN KHÔNG THỂ.

Giải thích: .NET remoting không cho phép bạn chọn kênh khách hàng nào sẽ sử dụng khi tạo đối tượng. Về phía máy chủ, nó sẽ sử dụng kênh lắng nghe cổng được đề cập, rõ ràng, nhưng ở phía máy khách, nó sẽ chỉ sử dụng bất kỳ thứ gì sẵn có hoặc thậm chí tạo ra một cái mới - mặc dù tôi luôn đăng ký của riêng mình.

Vì vậy, có vẻ như (tôi không thể tìm thấy nó ở bất kỳ đâu trong tài liệu) rằng nếu có một kênh khách hàng bảo mật có sẵn, kênh đó sẽ được sử dụng. Vì vậy, ví dụ trong câu hỏi, đối tượng từ xa được tạo ra đối với kênh an toàn, nhưng nó mong đợi một cái không an toàn - do đó nó không thành công. Trong trường hợp tạo kết nối không an toàn trước tiên - nó hoạt động bởi vì tại thời điểm đối tượng ở xa được tạo ra, không có kênh máy khách bảo mật, do đó kênh khách hàng không an toàn được sử dụng.

CÁCH GIẢI QUYẾT:

  1. Tạo một AppDomain riêng cho, ví dụ, kênh an toàn.
  2. Trong đó AppDomain, tạo một đối tượng khách hàng sẽ kết nối với bảo mật.
  3. Sử dụng Tên miền mặc định của bạn cho tất cả các kênh không an toàn.