WCF Canal Duplex: Vérifier si la fonction de rappel canal est toujours disponible
J'ai le problème suivant. Je suis en train d'écrire un logiciel de chat. Le client/serveur mécanisme est basé sur DualHttpBinding de la WCF. Cela signifie que si un utilisateur envoie un message à tous les clients qui sont dans la salle où le message a été envoyé, sont notifiées par le serveur.
Je veux m'assurer, que si un client de l'application se bloque (whyever), le client objet est retiré de la salle de listes.
Est-il une possibilité de vérifier le rappel du canal de l'état avant d'appeler une opération de rappel? Le problème, c'est que si je l'appelle une opération sur un client qui n'est plus connecté (à cause d'un imprévu crash), le service va s'accrocher.
public YagzResult SendMessage(Message message)
{
foreach (ChatNodeAddress chatNodeAddress in message.Destination)
{
ChatNode chatNode = chatProvider.FindChatNode(chatNodeAddress);
if (chatNode != null)
{
User currentUser = CurrentUser;
foreach (User user in chatNode)
{
//Don't notify the current client. Deadlock!
if (!user.Equals(currentUser))
{
//Get the callback channel here
IYagzClient client = GetClientByUser(user);
if (client != null)
{
//--> If the client here called is not any more available,
//the service will hang <---
client.OnChatMessageReceived(message);
}
}
}
}
else
{
return YagzResult.ChatNodeNotFound;
}
}
return YagzResult.Ok;
}
Comment puis-je vérifier si un client est toujours à l'écoute? BTW, les opérations dites sur le client sont tous déclarés OneWay et la ConcurrencyMode est réglé à "Plusieurs".
Merci à vous tous!
Accueille,
Simon
OriginalL'auteur Simon | 2009-12-30
Vous devez vous connecter pour publier un commentaire.
Vous pouvez lancer contrat de rappel à ICommunicationObject et ensuite vérifier l'état de canal.
OriginalL'auteur Gokhan Demir
Il y a des événements sur un CommunicationObject (c'est à dire de rappel de canal) pour Fermé et Faillées. Vous pouvez ajouter des gestionnaires de ces et suivre les clients ont encore valide d'un canal disponible.
Vous pouvez aussi jeter un oeil à la IChannelInitializer classe pour mettre en œuvre le suivi des clients.
OriginalL'auteur Kwal
Le principal problème était que je ne voulais pas faire d'exceptions, à l'exception d'un TimeoutException. Mon service a été bloquée pendant 1 min (le délai d'attente j'ai mis), jusqu'à ce que l'exception a été congédié.
J'ai résolu ce problème grâce à la solution de contournement suivante. Au lieu d'appeler le client de rappel sur le fonctionnement actuel de fil de travail du service, j'ai créé un nouveau thread qui appelle le client de l'opération de rappel et attend une TimeoutException. Si le délai d'attente se produit, l'utilisateur est tout simplement retiré de la salle, dans les listes, il appartenait à.
Ceci est un extrait de code qui montre comment j'ai fait:
Au début, j'ai créé une classe qui représente un simple appel pour le client:
Supposons que le code suivant est une partie d'une méthode qui informe tchat clients qu'un nouveau message a été écrit:
Je viens de créer un nouveau YagzClientAsyncCall-Objet et laissez l'opération doit être appelée sur un nouveau thread.
OriginalL'auteur Simon