Il n'est pas possible de définir un délai d'attente de connexion pour un appel distant .NET. Documentation fait parfois référence à TcpChannel propriétés qui prétendument le faire, mais discussions et le plus récent docs que j'ai trouvé indiquent que ce n'est pas possible. On peut définir un délai d'expiration sur l'appel distant lui-même, mais pas sur la tentative de connexion initiale. Vous êtes bloqué avec le délai par défaut de 45 secondes.Vérification de la présence du serveur distant .NET - Mon approche est-elle correcte?
Pour diverses raisons, je ne peux pas utiliser WCF.
Cela provoque un problème lorsque le serveur distant disparaît. Si je tente de faire un appel à distance, je suis bloqué pour ces 45 secondes. Ce n'est pas bon. Je veux vérifier la présence du serveur distant. Ping il avec une PingTimeout
est l'approche la plus simple, mais je veux vérifier spécifiquement pour le serveur distant, par opposition à seulement la machine en cours.
Après quelques essais, je suis venu avec cette approche:
- commencent une connexion Asynchrone socket TCP au port d'accès distant.
- Attendez la fin de la connexion, ou un délai d'attente pour expirer (en utilisant un ManualResetEvent).
- Si la connexion asynchrone a réussi, renvoie succès. Sinon, retournez l'échec.
Cela fonctionne, mais je ne suis pas sûr de mon utilisation de mon WaitHandle
et socket. Je voudrais également assurer des vérifications concurrentes WRT thread-sécurité, que je pense avoir fait. Mon code est ci-dessous. Voyez-vous des problèmes avec mon approche?
private static bool IsChannelOpen(string ip, int port, int timeout)
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ip), port);
Socket client = new Socket(endpoint.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
SocketTestData data = new SocketTestData()
{ Socket = client, ConnectDone = new ManualResetEvent(false) };
IAsyncResult ar = client.BeginConnect
(endpoint, new AsyncCallback(TestConnectionCallback), data);
// wait for connection success as signaled from callback, or timeout
data.ConnectDone.WaitOne(timeout);
client.Close();
return data.Connected;
}
private static void TestConnectionCallback(IAsyncResult ar)
{
SocketTestData data = (SocketTestData)ar.AsyncState;
data.Connected = data.Socket.Connected;
if (data.Socket.Connected)
{
data.Socket.EndConnect(ar);
}
data.ConnectDone.Set(); // signal completion
}
public class SocketTestData
{
public Socket Socket { get; set; }
public ManualResetEvent ConnectDone { get; set; }
public bool Connected { get; set; }
}
J'ai toujours détesté ça à propos de Remoting. –