2010-03-30 17 views
19

No puedo utilizar un canal no seguro una vez que un canal seguro ya ha sido registrado. El siguiente código funciona solo si en el lado del cliente, el canal no seguro está registrado anteriormente.Mezcla de canales seguros y no seguros

¿Es posible mezclar canales seguros y no seguros sin ninguna restricción en la orden de registro?

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

Editar: Sin cambios con .NET 4 y VS 2010.

+3

Usted dice que "no funciona"; ¿Podrías aclarar qué está haciendo? –

+0

@ M.Babcock Su comentario es sobre una pregunta muy antigua, para usarla que no ha estado en uso durante unos meses. Sólo fyi –

+0

Sabía que era una pregunta bastante antigua, pero pensé que todavía es relevante ya que los moderadores no la han desactivado todavía. Siéntete libre de borrar mi respuesta si crees que es innecesaria. –

Respuesta

1

Esto se pregunta interesante vendimia, he pasado alrededor de una semana tratando de resolver este problema, y ​​tuvo que aplicar una solución alternativa. Pero esto es lo que he descubierto: la respuesta es más probable: NO, NO PUEDES.

Explicación: .NET remoto no le permite elegir qué canal de cliente utilizar al crear un objeto. Por el lado del servidor, usaría el canal escuchando el puerto en cuestión, obviamente, pero del lado del cliente usaría cualquier disponible o incluso crearía uno nuevo, aunque siempre registro el mío.

Parece (no pude encontrarlo en ningún lugar de la documentación) que si hay un canal de cliente seguro disponible, ese se acostumbra. Así que, por ejemplo, en la pregunta, el objeto remoto se crea contra el canal seguro, pero espera uno inseguro, por lo que falla. En caso de crear una conexión insegura primero, funciona porque en el momento en que se crea el objeto remoto no hay un canal de cliente seguro, por lo que se utiliza el canal de cliente inseguro.

Solución:

  1. Crear un dominio de aplicación independiente para, por ejemplo, canal seguro.
  2. En ese AppDomain, cree un objeto de cliente que se conectaría a la seguridad.
  3. Utilice su AppDomain predeterminado para todos los canales inseguros.
Cuestiones relacionadas