Pro du dev COM/OLE : Erreur $80010001 (L'appel a été rejeté...) - Delphi/Pascal - Programmation
Marsh Posté le 21-01-2010 à 10:28:33
J'ai trouvé la cause :
http://msdn.microsoft.com/en-us/li [...] 85%29.aspx
En bas on peut lire :
"If a client implements IMessageFilter and calls a server method on a remote machine, RetryRejectedCall will not be called"
Je suis vert, je n'ai donc pas de solution et en plus j'ai mis 3 jours à trouver cette note !
Marsh Posté le 20-01-2010 à 16:34:35
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 provoque des erreurs mémoire lorsque les arguments sont de type chaînes de caractères, pour une raison que j'ignore (j'ai surchargée directement la méthode "DispCallByID" ).
Merci d'avance pour votre aide.
Message édité par ZZZzzz le 21-01-2010 à 09:48:06