Aux Pros du dev COM/OLE : Erreur $80010001 (L'appel a été rejeté par l'appelé) m

pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010 - 20 janv. 2010 à 16:45
pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010 - 16 févr. 2010 à 12:03
Bonjour à tous,

je rencontre le problème suivant :



je développe une application doté d'un serveur COM hors processus (il s'agit d'un exe) et de modules clients de ce serveur COM.

Tout se passe bien tant que les modules et le serveur COM fonctionne sur la même machine physique. Par contre si le module est lancé depuis une autre machine celui-ci se connecte au serveur COM facilement mais j'ai plein d'erreurs OLE $80010001 "L'appel a été rejeté par l'appelé".
En effet mes modules peuvent êtres amenés à rejeter temporairement des appels sous certaines conditions. C'est pourquoi j'ai implémenté côté client et côté serveur une interface "IOLEMessageFilter".

Côté client j'ai implémenté "HandleInComingCall" pour rejeter l'appel en spécifiant "SERVERCALL_RETRYLATER" (et non "SERVERCALL_REJECTED" ) afin que le serveur recommence l'appel plus tard. Côté serveur j'ai implémenté la méthode "RetryRejectCall" pour retourner "100" ce qui signifie "retenter l'appel dans 100 ms" (pour info le client possède la même implémentation de cette méthode).

Le problème est que si le client provient d'un autre ordinateur alors la méthode "RetryRejectCall" n'est jamais appelé dans le serveur, à la place j'obtiens directement l'erreur OLE décrite.
J'ai vérifié que l'appel à "RegisterFilter" se fasse bien sur le serveur, et dans la même thread que celle qui me provoque l'erreur plus tard, du coup je sèche un peu.... comment se fait-il que la méthode "RetryRejectCall" ne soit pas appelée côté serveur ?

Quelques précisions :

- Des méthodes sont appelés depuis les clients vers le serveur (appel sortant du point de vue du client), et depuis le serveur vers le client (appel entrant du point de vue du client). Dans ce dernier cas il s'agit souvent d'un événement de retour généré depuis l'appel du client (ce qui provoque une réentrance avec des appels marqués "CALLTYPE_NESTED", ces appels sont forcément acceptés et ne posent donc pas de soucis), mais pas forcément.

- J'ai imposé le même modèle de cloisonnement sur les 2 threads (apartment) avant l'enregistrement du filtre, ce qui est sans effet.

Enfin j'ai tenté de rattrapper l'exception côté serveur pour rebalancer moi-même l'appel plus tard mais cela m'oblige à bloquer la thread et donc je génère un deadlock si l'appel n'est pas "nested" (provoqué par le client) puisque pendant ce temps le serveur ne peut plus accepter d'appels entrants (de point de vue serveur cette fois donc).


Merci d'avance pour votre aide.

ZZZzzz...

8 réponses

JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
20 janv. 2010 à 17:45
J'ai vomi.
0
pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010
21 janv. 2010 à 09:19
Désolé je sais que ça peut paraître un peu obscure, mais une personne ayant déjà utilisé l'interface 'IMessageFilter' dans le cadre d'appels COM/DCOM doit voir de quoi je parle.

D'ailleurs je reviens sur la dernière partie de mon post, le fait de rattrapper l'exception côté serveur pour relancer l'appel ne bloque pas la thread complètement. En effet à chaque tentative de refaire l'appel sortant, un appel entrant peut avoir lieu. C'est donc bien à ce moment que la thread rentre dans une boucle traitant les messages.
Mais je n'arrive pas à gérer les exceptions directement en surchargeant la méthode des appels 'DispCall', cela me provoque des erreurs mémoire lorsque les arguments passés contiennent des chaînes de caractères.

Je veux bien donner toutes précisions susceptibles de vous aider...

ZZZzzz...
0
JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
21 janv. 2010 à 09:31
Je ne voulais pas etre impoli à répondre à coté de la plaque, mais j'avoue que c'est hors de ma portée et de mon niveau !
Pardon pour cette polution humoristique :)
En esperant que tu trouves quelqu'un à la hauteur de ta question :p
0
pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010
21 janv. 2010 à 10:33
Non y'a pas de soucis j'avais plus ou moins compris ;-).

Bon j'ai trouvé la cause à mon problème :

http://msdn.microsoft.com/en-us/library/ms680739%28VS.85%29.aspx

Jusqu'à présent je n'avais pas vu la petite note "If a client implements IMessageFilter and calls a server method on a remote machine, RetryRejectedCall will not be called"

Ca fait quand même plusieurs jours que je cherche, j'ignore comment j'ai pu louper ce détail, mais du coup je n'ai pas de solution à mon problème et je suis donc très embêté...



ZZZzzz...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
JulioDelphi Messages postés 2226 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 18 novembre 2010 14
21 janv. 2010 à 10:41
Attention, j'ai dévalidé les "réponses acceptée" car sinon ça valide que le post a eu sa réponse.
0
pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010
21 janv. 2010 à 19:02
Ok, mais il n'y aura pas de réponse, je vais devoir trouver une autre solution, moins propre, plus longue et imparfaite. J'ai quand même envoyé un email au support de Microsoft sans trop esperer de réponse. Je trouve que c'est une sérieuse limitation voir un bug (il n'y a pas d'explication sur le pourquoi ça n'appelle pas la méthode "RetryRejectedCall").


ZZZzzz...
0
mOULf Messages postés 1 Date d'inscription vendredi 27 juin 2003 Statut Membre Dernière intervention 15 février 2010
15 févr. 2010 à 16:26
Bonjour, j'ai à peu de choses près le même souci (je n'utilise pas DCOM) et cela va faire 4 jours que je me prends la tête avec.
J'ai un serveur COM qui fait appel à d'autres composants COM et je rencontre le souci lorsque je créée des composants AutoCAD 2010.

J'ai résolu une parti de mon problème en implémentant l'interface IMessageFilter sur des Composants COM intermédiaires fait en .NET. Dans ce cas, le RetryRejectedCall est bien lancé.

Dans d'autres cas par contre, je ne peux (pour l'instant) pas faire d'intermédiaire et suis obligé de piloter via COM depuis mon serveur en C++.
Après avoir implémenté l'interface IMessageFilter je m'apercevais que certains appels étaient bien interceptés et d'autres non. En fait je viens de comprendre que certains appels COM ne sont pas faits depuis le même thread d'exécution, ce qui fait que les messages COM ne sont pas renvoyés dans la bonne boucle de gestion des messages.
Dans mon cas, je créée les composants depuis des threads de travail (workers thread simple en C) sur lesquels je pense que je n'arriverai pas à implémenter le IMessageFilter.
Histoire compliquée d'appartements, de Threads et de messages toussa
Je crois que je vais aussi devoir trouver une solution alternative!
0
pdallongeville Messages postés 5 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 16 février 2010
16 févr. 2010 à 12:03
Bonjour moulf,

Je suis content de voir que je ne suis pas seul dans les galères du développement COM/DCOM.

J'ai eu une réponse de Microsoft (comme quoi) qui me demandait s'il n'y avait pas une autre solution que celle d'utiliser un "MessageFilter". Evidemment il y a toujours une autre solution mais en gros c'est de tout refaire différemment (bien trop coûteux). En attendant j'ai géré au cas par cas là où ça me posait des soucis, ce qui m'a demandé pas mal de modifications sans être certains de ne pas avoir d'autres soucis plus tard dans d'autres cas :-/...

Pour ma part les appels sont heureusement effectués tous depuis la même thread (moins performant mais bien plus simple à gérer) et donc le même "appartement", je n'ai donc pas ton problème. Mais en contrepartie j'utilise le DCOM qui pose pas mal de problèmes dont celui de ne pas entrainer d'appels à la méthode "RetryRejectedCalls"... Si quelqu'un connait une solution...


ZZZzzz...
0
Rejoignez-nous