Objetos utilizables de forma remota
Los objetos utilizables de forma remota son aquéllos que funcionan correctamente en un entorno altamente distribuido. Hay dos tipos principales de objetos utilizables de forma remota:
- Objetos de cálculo de referencias por valor, de los que se realizan copias que se pasan fuera del dominio de aplicación.
- Objetos de cálculo por referencia, para los que se crea un proxy que el cliente utiliza para obtener acceso a ellos de forma remota.
Objetos de cálculo de referencias por valor
Los objetos MBV (Marshal-By-Value, cálculo de referencias por valor) declaran sus reglas de serialización (ya sea mediante ISerializable para implementar su propia serialización o bien mediante el uso de un SerializableAttribute, que indica al sistema que serialice el objeto automáticamente) pero no extienden MarshalByRefObject. El sistema de interacción remota realiza una copia completa de estos objetos y se la pasa al dominio de aplicación que hace la llamada. Una vez que la copia está en el dominio de aplicación del llamador, las llamadas a la copia se dirigen directamente a esa copia. Además, los objetos MBV que se pasan como argumentos, también se pasan por valor. Aparte de declarar el atributo SerializableAttribute o de implementar ISerializable, no tiene que hacer nada para pasar las instancias de su clase por valor a través de los límites de las aplicaciones o de los contextos.
Nota Empezando con la versión 1.1 de .NET Framework, la infraestructura de interacción remota no deserializa automáticamente determinados tipos en el servidor. Si en su caso es así, es preciso establecer el nivel de deserialización del servidor en Full para que el servidor pueda deserializar y utilizar el objeto MBV. Para obtener más información, vea Deserialización automática en .NET Remoting.
Utilice objetos MBV cuando, por razones de rendimiento o de procesamiento, convenga mover todo el estado del objeto y su funcionalidad de ejecución al dominio de aplicación de destino. En muchos escenarios, este método reduce el número de largos viajes de ida y vuelta a través de redes, el número de procesos y el de dominios de aplicación que usan recursos. Los objetos MBV también se utilizan directamente desde el interior del dominio de aplicación original del objeto. En este caso, debido a que no se realiza ningún cálculo de referencias, no se efectúa ninguna copia y el acceso es muy eficaz.
Por otro lado, si los objetos publicados son muy grandes, puede que pasar una copia completa por una red con mucho tráfico no sea la opción idónea para la aplicación. Además, los cambios introducidos en el estado del objeto copiado nunca se comunican al objeto original ubicado en el dominio de aplicación de origen. En un plano abstracto, este escenario es parecido al de una página HTML estática solicitada por un explorador de cliente. El servidor copia el archivo, lo escribe en una secuencia, lo envía y se olvida de él. Toda solicitud posterior es, simplemente, otra solicitud de otra copia.
El sistema de interacción remota utiliza mucho los objetos serializables. Una referencia a un objeto ubicado en otro dominio de aplicación y representada en el sistema de interacción remota por la clase ObjRef es en sí misma serializable: tiene que ser posible hacer una copia exacta del objeto y enviarla a donde se solicite. Los objetos de mensaje que implementan IMessage porque son los contenedores genéricos de la información de llamada y de cualquier otra referencia necesaria a un objeto. Además, los objetos que simplemente transmiten datos suelen ser objetos serializables. Por ejemplo, DataSet extiende MarshalByValueComponent, que implementa ISerializable.
Excepciones de interacción remota definidas por el usuario
Las excepciones definidas por el sistema son todos los tipos de cálculo de referencias (implementan la interfaz ISerializable) que, cuando las inicia un objeto remoto, se copian automáticamente al llamador si lo permite la configuración remota. (Empezando con la versión 1.1 de .NET Framework, el elemento <customErrors> debe establecerse en off para que las excepciones puedan fluir hasta el llamador.)
Para crear sus propios tipos de excepción que pueden iniciar los objetos remotos y pueden ser detectados por llamadores remotos, siga este procedimiento:
- Implementar ISerializable.
- Coloque el atributo SerializableAttribute en la clase.
- Implemente un constructor de deserialización que adopta un objeto SerializationInfo y un objeto StreamingContext como parámetros.
En el siguiente ejemplo de código C#, se muestra una sencilla implementación que, si se configura correctamente, se vuelve a copiar al llamador cuando la inicie el objeto servidor remoto.
[Serializable]
public class CustomRemotableException : RemotingException, ISerializable {
private string _internalMessage;
public CustomRemotableException(){
_internalMessage = String.Empty;
}
public CustomRemotableException(string message){
_internalMessage = message;
}
public CustomRemotableException(SerializationInfo info, StreamingContext context){
_internalMessage = (string)info.GetValue("_internalMessage", typeof(string));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context){
info.AddValue("_internalMessage", _internalMessage);
}
// Returns the exception information.
public override string Message{
get {
return "This is your custom remotable exception returning: \""
+ _internalMessage
+ "\"";
}
}
}
Objetos de cálculo por referencia
Los objetos MBR (Marshal-By-Reference, cálculo por referencia) son aquéllos utilizables de forma remota que extienden al menos System.MarshalByRefObject. Dependiendo del tipo de activación declarado, cuando un cliente crea una instancia de un objeto MBR en su propio dominio de aplicación, la infraestructura de .NET remoting crea un objeto proxy en el dominio de aplicación del llamador que represente al objeto MBR y devuelve al llamador una referencia a dicho objeto proxy. A partir de ese momento, el cliente realiza las llamadas en el proxy. La interacción remota calcula las referencias de esas llamadas, las devuelve al dominio de aplicación de origen e invoca al objeto propiamente dicho.
Nota Si el cliente se encuentra en el mismo dominio de aplicación que el objeto MBR, la infraestructura devuelve al cliente una referencia directa al objeto MBR, evitando así la sobrecarga asociada al cálculo de referencias.
Si se pasa MarshalByRefObject como parámetro, se convierte en un proxy en el otro dominio de aplicación cuando llega la llamada. Los valores devueltos MBR y los parámetros out funcionan de la misma manera.
Nota Empezando con la versión 1.1 de .NET Framework, la infraestructura de interacción remota no deserializa automáticamente determinados tipos en el servidor. Por ejemplo, para admitir los objetos MBR pasados como parámetros, es preciso establecer el nivel de deserialización del servidor en Full para que el servidor pueda deserializar y utilizar el parámetro MBR. Para obtener más información sobre este y otros escenarios, vea Deserialización automática en .NET Remoting.
Debería utilizar objetos MBR cuando el estado del objeto y de todas las funcionalidades ejecutables deba permanecer en el dominio de aplicación en el que fue creado. Por ejemplo, un objeto con un campo interno que es un identificador del sistema operativo debería extender MarshalByRefObject porque el identificador del sistema operativo no tendría sentido en otro dominio de aplicación de otro proceso o de otro equipo. A veces, el objeto es sumamente grande, lo que puede no representar un problema en un servidor de gran eficacia, pero sí es un inconveniente si se debe enviar a través de una conexión a un módem de 33,6 kbps.
Objetos enlazados a un contexto
Los objetos enlazados a un contexto son objetos MBR que se heredan de System.ContextBoundObject, que a su vez se hereda de System.MarshalByRefObject. Un contexto puede considerarse como una subdivisión de un dominio de aplicación que proporciona un entorno completo a los objetos que residen en él durante su ejecución. Por ejemplo, un contexto puede garantizar que no será posible que varios subprocesos obtengan acceso simultáneamente a los objetos. Cada dominio de aplicación tiene un contexto predeterminado. La mayor parte del código administrado crea objetos y llama a miembros directamente desde el mismo dominio de aplicación utilizando el contexto predeterminado de ese dominio, sin que se produzcan problemas relacionados con el contexto. Todos los tipos que se heredan de ContextBoundObject se exponen como objetos proxy ante otros contextos (tanto en el mismo dominio como en otros).
Por ejemplo, imagine que tiene un método en un tipo que forma parte de una transacción y, por lo tanto, depende de las reglas específicas del contexto en el que fue creado. Ese tipo debe heredar de ContextBoundObject, de manera que se pueda obtener acceso al objeto desde su propio contexto y el sistema pueda imponer las reglas relativas a las transacciones asociadas con ese objeto y sus métodos. Si se llama a ContextBoundObject desde otro contexto del mismo dominio de aplicación, se crea un proxy para el llamador, pero la comunicación entre contextos no pasa por el sistema de canales, con lo que mejora la eficacia de la llamada en esta situación.
Dado que cruzar cada límite conlleva su correspondiente tiempo de procesamiento, deberá determinar qué límites debe cruzar su objeto antes de decidir qué tipo de objeto utilizable de forma remota debería ser su servidor. Sólo se puede obtener acceso a los objetos específicos de un determinado contexto directamente desde ese contexto. Lo mismo se aplica a los objetos específicos de un determinado dominio de aplicación. Para utilizar de forma remota cualquiera de estos objetos, el sistema de interacción remota debe atravesar los límites de un contexto, los límites de una aplicación o ambos, para poder llamar al objeto servidor desde el interior de sus límites propios. Si no necesita una comprobación de contexto para llamar a su objeto, no debe hacer que su tipo remoto extienda ContextBoundObject; MarshalByRefObject dará mejores resultados. Si necesita comprobar el contexto, debe extender ContextBoundObject, pero tenga claro que hay que cruzar el límite adicional antes de que se realice la llamada al objeto.
Vea también
Objetos utilizables y no utilizables de forma remota | ContextBoundObject | Objetos no utilizables de forma remota