Domanda

Si tratta del momento in cui viene generata un'eccezione di comunicazione remota .NET.Se dai un'occhiata a MSDN, verrà menzionato che viene generata un'eccezione di comunicazione remota quando qualcosa va storto con la comunicazione remota.Se il mio server non è in esecuzione, ricevo un'eccezione socket che va bene.

Quello che sto cercando di capire è:ottenere un'eccezione remota indica con certezza che il mio server è attivo e funzionante?Se sì, ciò risolverebbe il problema.Altrimenti:C'è un modo per capire se l'eccezione remota ha avuto origine sul lato client o sul lato server?

Aggiornamento:

Il problema che sto cercando di risolvere è che inizialmente il server è inattivo e quindi il client invia un messaggio al server.Ora ricevo un'eccezione socket che dice "Non è stato possibile stabilire alcuna connessione..." il che va bene.

C'è un thread che invia messaggi al server a intervalli regolari per vedere se il server è disponibile.Ora, il server si avvia e, a quel punto, potresti ottenere la risposta che va bene oppure potresti ottenere qualche eccezione e molto probabilmente sarà un'eccezione remota.Quindi, quello che sto cercando di chiedere è che:nel caso in cui non ricevo un messaggio e ottengo un'eccezione remota, è possibile che il server sia attivo e funzionante e riceva ancora questa eccezione?

Tutto quello che sto facendo è semplicemente chiamare un metodo sull'oggetto remoto che non fa nulla e restituisce.Se non ci sono eccezioni, allora sto bene.Ora, se c'è un'eccezione remota e se sapevo che l'eccezione remota si è verificata sul server, allora so che, nonostante abbia ottenuto l'eccezione, sono connesso al server.

È stato utile?

Soluzione

Ottenere un'eccezione remota non garantisce che il tuo server sia attivo e funzionante.Se qualcos'altro è in esecuzione e in ascolto su quella porta, la connessione avrà successo e non si otterrà un'eccezione socket.Ciò che accade in questo caso dipende da come si comporta l'applicazione che ha effettivamente ottenuto la connessione, ma probabilmente finirà per generare un'eccezione remota nel tuo client.

Ci vorrebbe un po' più di indagine per verificarlo, ma credo che l'eccezione remota indichi un problema nelle comunicazioni tra il client e il server, quindi non c'è un "lato client" o un "lato server" che l'ha generata.Vuol dire che i due non parlavano allegramente e la causa potrebbe essere stata uno dei due.

Altri suggerimenti

Se intendi utilizzare tipi di eccezioni personalizzati da generare oltre il limite remoto, assicurati di contrassegnare questi tipi come "[Serializable]".Non riesco a ricordare l'esatto messaggio di errore, ma la prima volta che l'ho visto sono rimasto perplesso per gran parte della giornata.

Inoltre, solo un suggerimento: TargetInvocationException spesso ha l'eccezione REAL incorporata nella sua proprietà InnerException.Non c'è niente di più inutile di "Un'eccezione è stata lanciata dal target di un'invocazione".

Prova ad assicurarti di inviare il messaggio corretto e che anche i messaggi ricevuti dal server siano corretti, ad es.utilizzando asserzioni (si chiama Design by Contract).Se hai questa possibilità, prova a eseguire il debug del lato server e del lato client contemporaneamente.(eseguendo due istanze VS contemporaneamente)

Non ho avuto accesso al codice sorgente della mia ultima applicazione remota, ma per quanto posso ricordare non siamo riusciti a trovare un modo per sapere con certezza se il server era attivo a causa di una qualsiasi delle eccezioni che abbiamo ottenuto.
Abbiamo controllato se la rete era presente e avvisato l'utente in caso contrario (credo un metodo sulla classe Environment).

Se la logica dell'applicazione lato server ha generato un'eccezione, dovrebbe essere in grado di eseguire il marshalling sul client per fargli sapere cosa è successo.Puoi testarlo lanciando deliberatamente un'eccezione in uno dei metodi dell'oggetto remoto.Quindi chiama quel particolare metodo dal lato client aspettandoti un'eccezione:

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

Puoi aspettarti un'eccezione ricevuta in questo modo

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

Dovrebbe dirti che l'origine è sul server, con un'analisi dello stack lato server.

Ok, ora che l'hai detto in questo modo, presumo che tu stia utilizzando TCP per la comunicazione remota, poiché se fosse tramite HTTP, verrebbe generata una WebException in caso di mancata connessione al server (porta di rete TCP).Quando il server non ha avviato il programma applicativo per registrare il canale su quella porta TCP designata, otterrai una SocketException.Dopo tutto, il server non ascolta/risponde a quella porta, come può mai il client stabilire una connessione socket?

Ma, se ottieni una RemotingException, è necessaria non significa necessariamente che il server ha la propria applicazione remota funzionante correttamente.Potresti testare connettendoti a un URI sbagliato su una porta sbagliata, come la porta 80 (IIS).

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

Ciò comporterebbe una RemotingException perché mentre il client può stabilire una connessione TCP alla porta 80, è IIS che risponde alla chiamata e non l'app Remoting;IIS non è in grado di gestire direttamente le chiamate remote.Detto questo, una RemotingException può anche significare un problema lato client.Questo articolo del blog può aiutarti a capire meglio.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top