Pregunta

Se trata de cuando se lanza una excepción remota de .NET.Si echa un vistazo a MSDN, mencionará que se genera una excepción de comunicación remota cuando algo sale mal con la comunicación remota.Si mi servidor no se está ejecutando, aparece una excepción de socket, lo cual está bien.

Lo que estoy tratando de averiguar es:¿Recibir una excepción remota indica con certeza que mi servidor está en funcionamiento?En caso afirmativo, eso resolvería el problema.Si no:¿Hay alguna manera de determinar si la excepción de comunicación remota se originó en el lado del cliente o en el lado del servidor?

Actualizar:

El problema que estoy tratando de resolver es que el servidor está inactivo inicialmente y luego el cliente envía algún mensaje al servidor.Ahora aparece una excepción de socket que dice "No se pudo establecer conexión...", lo cual está bien.

Hay un hilo que envía mensajes al servidor a intervalos regulares para ver si el servidor está disponible.Ahora, aparece el servidor y, en ese momento, podría obtener la respuesta, lo cual está bien, o podría obtener alguna excepción y lo más probable es que sea una excepción remota.Entonces, lo que intento preguntar es que:En caso de que no reciba un mensaje y obtenga una excepción remota, ¿existe la posibilidad de que el servidor esté en funcionamiento y sigo recibiendo esta excepción?

Todo lo que hago es simplemente llamar a un método en el objeto remoto que no hace nada y regresa.Si no hay excepción entonces estoy bien.Ahora, si hay una excepción de comunicación remota y si sabía que la excepción de comunicación remota ocurrió en el servidor, entonces sé que, a pesar de recibir la excepción, estoy conectado al servidor.

¿Fue útil?

Solución

Obtener una excepción remota no garantiza que su servidor esté en funcionamiento.Si algo más se está ejecutando y escuchando en ese puerto, la conexión se realizará correctamente y no obtendrá una excepción de socket.Lo que sucede en este caso depende de cómo se comporta la aplicación que realmente obtuvo su conexión, pero probablemente terminará generando una excepción remota en su cliente.

Se necesitaría un poco más de investigación para verificar esto, pero creo que la excepción de comunicación remota indica un problema en las comunicaciones entre el cliente y el servidor, por lo que no hay un "lado del cliente" o un "lado del servidor" que lo haya generado.Significa que los dos no estaban hablando alegremente y podría haber sido causado por cualquiera de los dos.

Otros consejos

Si tiene la intención de utilizar tipos de excepción personalizados para lanzarlos a través del límite remoto, asegúrese de marcar estos tipos como "[Serializable]".No recuerdo el mensaje de error exacto, pero la primera vez que lo vi me dejó perplejo durante la mayor parte del día.

Además, solo un consejo, TargetInvocationException a menudo tiene la excepción REAL incrustada en su propiedad InnerException.No hay nada más inútil que "El objetivo de una invocación lanzó una excepción".

Intente asegurarse de enviar el mensaje correcto y que los mensajes recibidos por el servidor también sean correctos, p.utilizando aserciones (se llama Diseño por Contrato).Si tiene esa posibilidad, intente depurar el lado del servidor y el lado del cliente al mismo tiempo.(ejecutando dos instancias de VS al mismo tiempo)

No tengo acceso al código fuente de mi última aplicación remota, pero hasta donde puedo recordar, no pudimos encontrar una manera de saber con certeza si el servidor estaba activo debido a alguna de las excepciones que obtuvimos.
Verificamos si la red estaba presente y advertimos al usuario si no (creo que es un método en la clase Entorno).

Si la lógica de la aplicación del lado del servidor generó una excepción, debería poder comunicarse con el cliente para informarle lo que sucedió.Puedes probar esto lanzando deliberadamente una excepción en uno de los métodos del objeto remoto.Luego llame a ese método particular desde el lado del cliente esperando una excepción:

HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);

IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
    typeof(IMyRemoteObject),
    "http://localhost:1234/MyRemoteObject.soap");
Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
    int tmp = obj.GetValue();
    Console.WriteLine("Client.Main(): Original server side value: {0}",tmp);
Console.WriteLine("Client.Main(): Will set value to 42");

try
{
    // This method will throw an ApplicationException in the server-side code.
    obj.SetValue(42);
}
catch (Exception ex)
{
    Console.WriteLine("=====");
    Console.WriteLine("Exception type: " + ex.GetType().ToString());
    Console.WriteLine("Message: " + ex.Message);
    Console.WriteLine("Source: " + ex.Source);
    Console.WriteLine("Stack trace: " + ex.StackTrace);
    Console.WriteLine("=====");
}

Puede esperar que se reciba una excepción como esta.

=====
Exception type: System.ApplicationException
Message: testing
Source: Server
Stack trace:
Server stack trace:
   at Server.MyRemoteObject.SetValue(Int32 newval) in i:\projects\remoting.net\ch03\01_singlecallobjects\server\server.cs:line 27
   at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at General.IMyRemoteObject.SetValue(Int32 newval)
   at Client.Client.Main(String[] args) in i:\projects\remoting.net\ch03\01_singlecallobjects\client\client.cs:line 29
=====

Debería indicarle que la Fuente está en el servidor, con un seguimiento de la pila del lado del servidor.

Bien, ahora que lo ha expresado de esa manera, supongo que está utilizando TCP para la comunicación remota, ya que si fuera a través de HTTP, se generaría una WebException al no poder conectarse al servidor (puerto de red TCP).Cuando el servidor no haya iniciado el programa de aplicación para registrar el canal en ese puerto TCP designado, obtendrá una SocketException.Después de todo, el servidor no está escuchando/respondiendo a ese puerto, ¿cómo puede el cliente establecer una conexión de socket?

Pero, si obtiene una RemotingException, es necesario no necesariamente significa que el servidor tiene su aplicación remota adecuada funcionando bien.Puede realizar la prueba conectándose a un URI incorrecto en un puerto incorrecto, como el puerto 80 (IIS).

IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
    typeof(IMyRemoteObject),
    "tcp://localhost:80/MyRemoteObject.rem");

Eso daría como resultado una RemotingException porque, si bien el cliente puede establecer una conexión TCP al puerto 80, es IIS el que responde a la llamada y no la aplicación Remoting;IIS no puede manejar llamadas remotas directamente.Dicho esto, una RemotingException también puede significar un problema en el lado del cliente.Este artículo de blog puede ayudarle a comprender mejor.

http://www.cookcomputing.com/blog/archives/000308.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top