J'ai un serveur qui a plusieurs clients C1 ... Cn à chacun desquels une connexion TCP est établie. Il y a moins de 10 000 clients.Accès séquentiel aux sockets asynchrones
Le protocole de message est basé sur une requête/réponse, où le serveur envoie une requête à un client, puis le client envoie une réponse.
Le serveur a plusieurs threads, T1 ... Tm, et chacun d'entre eux peut envoyer des requêtes à l'un des clients. Je veux m'assurer qu'un seul de ces threads puisse envoyer une requête à un client spécifique à un moment donné, tandis que les autres threads voulant envoyer une requête au même client devront attendre.
Je ne veux pas empêcher les threads d'envoyer des requêtes à différents clients en même temps.
E.g. Si T1 envoie une requête à C3, un autre thread T2 ne devrait pas pouvoir envoyer quoi que ce soit à C3 tant que T1 n'a pas reçu sa réponse.
Je pensais à l'aide d'une déclaration de verrouillage simple sur la prise:
lock (c3Socket)
{
// Send request to C3
// Get response from C3
}
J'utilise les sockets asynchrones, donc je dois utiliser le moniteur à la place:
Monitor.Enter(c3Socket); // Before calling .BeginReceive()
Et
Monitor.Exit(c3Socket); // In .EndReceive
Je suis préoccupé par les choses qui ne vont pas et qui ne lâchent pas le moniteur, bloquant ainsi tous les acc ess à un client. Je pense que mon thread de battement de coeur pourrait utiliser Monitor.TryEnter() avec un timeout et jeter des sockets pour lesquelles il ne peut pas obtenir le moniteur.
Serait-il sensé de rendre les appels Begin et End synchrones afin de pouvoir utiliser l'instruction lock()? Je sais que je sacrifierais la concurrence pour la simplicité dans ce cas, mais cela en vaut peut-être la peine.
Suis-je surplombant quelque chose ici? Toute contribution appréciée.
Je suis déjà en train d'encapsuler le socket dans un objet (que j'ai appelé SocketHolder), donc cela semble être un endroit évident pour mettre le statut libre/occupé. Merci pour l'idée. –