Pergunta

Trata-se de quando uma exceção de comunicação remota do .NET é lançada.Se você der uma olhada no MSDN, ele mencionará que uma exceção de comunicação remota é lançada quando algo dá errado com a comunicação remota.Se meu servidor não estiver em execução, recebo uma exceção de soquete, o que é bom.

O que estou tentando descobrir é:obter uma exceção de comunicação remota indica com certeza que meu servidor está funcionando?Se sim, isso resolveria o problema.Se não:Existe uma maneira de descobrir se a exceção de comunicação remota se originou no lado do cliente ou no lado do servidor?

Atualizar:

O problema que estou tentando resolver é que o servidor fica inativo inicialmente e então o cliente envia alguma mensagem para o servidor.Agora recebo uma exceção de soquete dizendo "Nenhuma conexão pôde ser feita...", o que é bom.

Existe um thread que envia mensagens ao servidor em intervalos regulares para verificar se o servidor está disponível.Agora, o servidor aparece e, nesse ponto, você pode obter a resposta que está correta ou pode obter alguma exceção e muito provavelmente será uma exceção remota.Então, o que estou tentando perguntar é que:caso eu não receba uma mensagem e receba uma exceção remota, há uma chance de o servidor estar funcionando e eu ainda estar recebendo essa exceção?

Tudo o que estou fazendo é chamar um método no objeto remoto que não faz nada e retorna.Se não houver exceção, então estou bem.Agora, se houver uma exceção de comunicação remota e se eu souber que a exceção de comunicação remota ocorreu no servidor, sei que, apesar de receber a exceção, estou conectado ao servidor.

Foi útil?

Solução

Obter uma exceção de comunicação remota não garante que seu servidor esteja funcionando.Se algo mais estiver sendo executado e escutando naquela porta, a conexão será bem-sucedida e você não receberá uma exceção de soquete.O que acontece neste caso depende de como o aplicativo que realmente obteve sua conexão se comporta, mas provavelmente acabará gerando uma exceção de comunicação remota em seu cliente.

Seria necessário um pouco mais de investigação para verificar isso, mas acredito que a exceção de comunicação remota indica um problema na comunicação entre o cliente e o servidor, portanto não há um "lado do cliente" ou "lado do servidor" que a gerou.Isso significa que os dois não estavam conversando alegremente e isso poderia ter sido causado por qualquer um deles.

Outras dicas

Se você pretende usar tipos de exceção personalizados para serem lançados no limite de comunicação remota, certifique-se de marcar esses tipos como "[Serializable]".Não me lembro da mensagem de erro exata, mas fiquei perplexo durante a maior parte do dia na primeira vez que a vi.

Além disso, apenas uma dica, TargetInvocationException geralmente tem a exceção REAL incorporada em sua propriedade InnerException.Não há nada mais inútil do que "Uma exceção foi lançada pelo alvo de uma invocação".

Tente garantir que você enviou a mensagem correta e que as mensagens recebidas pelo servidor também estão corretas, por exemplo.usando asserções (é chamado Design by Contract).Se você tiver essa possibilidade, tente depurar o lado do servidor e o lado do cliente ao mesmo tempo.(executando duas instâncias do VS ao mesmo tempo)

Não tenho acesso ao código-fonte do meu último aplicativo de comunicação remota, mas, pelo que me lembro, não conseguimos descobrir uma maneira de saber com certeza se o servidor estava ativo devido a alguma das exceções que obtivemos.
Verificamos se a rede estava presente e avisamos o usuário caso não estivesse (um método na classe Environment, eu acho).

Se a lógica do aplicativo do lado do servidor gerou uma exceção, ela deverá ser capaz de enviar para o cliente para informar o que aconteceu.Você pode testar isso lançando deliberadamente uma exceção em um dos métodos do objeto remoto.Em seguida, chame esse método específico do lado do cliente, esperando uma exceção:

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

Você pode esperar uma exceção recebida assim

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

Deve informar que a fonte está no servidor, com um rastreamento de pilha do lado do servidor.

Ok, agora que você colocou dessa forma, presumo que você esteja usando TCP para comunicação remota, pois se fosse via HTTP, seria uma WebException lançada ao não conseguir se conectar ao servidor (porta de rede TCP).Quando o servidor não tiver iniciado o programa aplicativo para registrar o canal naquela porta TCP designada, você receberá uma SocketException.Afinal, o servidor não está escutando/respondendo a essa porta, como o cliente pode fazer uma conexão de soquete?

Mas, se você obtiver uma RemotingException, será necessário não significa necessariamente que o servidor tem seu aplicativo Remoting adequado funcionando bem.Você poderia testar conectando-se a um URI errado em uma porta errada, como a porta 80 (IIS).

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

Isso resultaria em uma RemotingException porque, embora o cliente possa fazer uma conexão TCP com a porta 80, é o IIS que responde à chamada e não o aplicativo Remoting;O IIS não pode lidar diretamente com chamadas remotas.Dito isto, uma RemotingException também pode significar um problema no lado do cliente.Este artigo do blog pode ajudá-lo a entender melhor.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top