Question

Ceci concerne le moment où une exception .NET Remoting est levée. Si vous jetez un coup d'œil à MSDN, il sera mentionné qu'une exception d'accès distant est levée en cas d'incident lié à l'accès distant. Si mon serveur ne fonctionne pas, j'obtiens une exception de socket qui convient.

Ce que j'essaie de comprendre est la suivante: l'obtention d'une exception d'accès distant indique-t-elle à coup sûr que mon serveur est opérationnel? Si oui, cela résoudrait le problème. Si ce n’est pas le cas: existe-t-il un moyen de savoir si l’exception à distance a son origine côté client ou côté serveur?

Mise à jour:

Le problème que je tente de résoudre est que le serveur est en panne au départ, puis que le client envoie un message au serveur. À présent, une exception de socket s'affiche: "Aucune connexion ne peut être établie ...". ce qui va bien.

Un thread envoie des messages au serveur à intervalles réguliers pour voir si le serveur est disponible. Maintenant, le serveur arrive, et à ce moment-là, vous pouvez obtenir une réponse satisfaisante ou une exception et il s'agira très probablement d'une exception distante. Donc, ce que j'essaie de demander, c'est que: si je ne reçois pas de message et si je reçois une exception distante, y at-il une chance que le serveur soit opérationnel et que je reçois toujours cette exception?

Tout ce que je fais est simplement d'appeler une méthode sur l'objet distant qui ne fait rien et retourne. S'il n'y a pas d'exception, je vais bien. Maintenant, s’il existe une exception de communication à distance et si je savais que l’exception de communication à distance s’est produite sur le serveur, je sais que malgré l’exception, je suis connecté au serveur.

Était-ce utile?

La solution

L'obtention d'une exception d'accès distant ne garantit pas que votre serveur est opérationnel. Si quelque chose d'autre s'exécute et écoute sur ce port, la connexion aboutira et vous n'obtiendrez pas d'exception de socket. Ce qui se passe dans ce cas dépend du comportement de l’application qui a obtenu votre connexion, mais elle finira probablement par générer une exception de communication à distance dans votre client.

Il faudrait un peu plus d'investigation pour vérifier cela, mais je pense que l'exception de communication à distance indique un problème de communication entre le client et le serveur. Il n'y a donc pas de "côté client". ou "coté serveur" cela l'a généré. Cela signifie que les deux ne parlaient pas joyeusement et que cela aurait pu être causé par l'un ou l'autre.

Autres conseils

Si vous envisagez d'utiliser des types d'exception personnalisés à travers la zone de délimitation à distance, assurez-vous de les marquer comme "[Serializable]". Je ne me souviens pas du message d’erreur exact, mais cela m’a rendu perplexe la première partie de la journée la première fois que je l’ai vu.

De plus, TargetInvocationException a souvent une exception REAL intégrée à sa propriété InnerException. Rien de plus inutile que "Une exception a été émise par la cible d'une invocation".

Essayez de vous assurer que vous envoyez le bon message et que les messages reçus par le serveur sont également corrects, par exemple. using assertions (on appelle Design by Contract). Si cela vous est possible, essayez de déboguer simultanément le côté serveur et le côté client. (exécution simultanée de deux instances de VS)

Je n'ai pas accès au code source de ma dernière application de communication à distance, mais si je me souviens bien, nous ne pouvions pas savoir si le serveur fonctionnait correctement, à l'exception des exceptions que nous avons reçues. .
Nous avons vérifié si le réseau était présent et avons averti l'utilisateur si ce n'est pas le cas (une méthode de la classe Environment, je pense).

Si la logique de l’application côté serveur a déclenché une exception, elle devrait pouvoir se diriger vers le client pour lui faire savoir ce qui s’est passé. Vous pouvez tester cela en lançant délibérément une exception dans l'une des méthodes de l'objet distant. Appelez ensuite cette méthode particulière du côté client dans l'attente d'une exception:

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

Vous pouvez vous attendre à une exception comme celle-ci

=====
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
=====

Il devrait vous indiquer que la source est sur le serveur, avec une trace de pile côté serveur.

Ok, maintenant que vous l'avez exprimé ainsi, je suppose que vous utilisez TCP pour la communication à distance, car si c'était via HTTP, il s'agirait d'une exception WebException lorsqu 'une connexion au serveur (port réseau TCP) échouait. Lorsque le serveur n'a pas lancé le programme d'application pour enregistrer le canal sur le port TCP désigné, vous obtenez une exception SocketException. Après tout, le serveur n’écoute pas / ne répond pas à ce port, comment le client peut-il établir une connexion socket?

Toutefois, si vous obtenez une exception RemotingException, elle ne doit pas signifier nécessairement que le serveur exécute correctement l'application Remoting appropriée. Vous pouvez tester en vous connectant à un mauvais URI sur un mauvais port, tel que le port 80 (IIS).

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

Cela donnerait lieu à une exception RemotingException car, si le client peut établir une connexion TCP sur le port 80, ce sont IIS qui répond à l'appel et non l'application Remoting. IIS ne peut pas gérer les appels distants directement. Cela dit, une exception RemotingException peut également signifier un problème du côté du client. Cet article de blog peut vous aider à mieux comprendre.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top