2009-04-09 6 views
0

J'ai un programme qui utilise Microsoft RPC pour la communication interprocessus. Lorsqu'un appel d'une méthode avec [in, chaîne] paramètres comme celui-ci (notation MIDL):"l'appel a échoué et n'a pas exécuté"

interface IOurInterface 
{ 
    error_status_t rpcMethod([in, string] const WCHAR* parameter); 
} 

est invoqué est généralement couronnée de succès. Mais si la chaîne de paramètre est suffisamment longue (plus de 3 millions de caractères environ), l'appel échoue avec RPC_S_CALL_FAILED_DNE ("L'appel de procédure distante a échoué et n'a pas été exécuté."). Cela dépend sûrement de la longueur de la chaîne. Le même appel dans les mêmes conditions réussit toujours si la chaîne est dans la limite et échoue toujours si la chaîne est plus longue. Il semble également que la limite dépend du système ou de la machine.

Quelqu'un at-il observé un tel comportement et quelle est la solution possible (sans raccourcir le paramètre)?

Répondre

1

J'ai déjà observé ce message mais je ne pense pas que c'était la même cause - le "n'a pas exécuté" est une erreur RPC générique qui peut être causée par beaucoup de choses.

Dans notre cas particulier, c'était parce que nous martelions WMI trop fort et ne nettoyions pas nos objets. Mais il semble que ce soit une cause différente dans votre cas.

Je sais que vous avez dit que vous ne souhaitiez pas raccourcir le paramètre mais que cela pourrait être la seule solution pour vous. J'ai du mal à visualiser les circonstances dans lesquelles vous devez envoyer 6M à travers un appel RPC. Peut-être que si vous expliquez les raisons derrière cela, nous pouvons vous aider plus loin.

Autres possibilités en fonction des commentaires à ce jour:

1/Segmentation. Les appels RPC limitent la quantité de données qui transitent sur le réseau

Cela peut être fait en segmentant le message à la source et en le reconstruisant à la destination, comme avoir trois paramètres (le serveur peut distribuer des identifiants de message dans un autre appel RPC ou trouver un autre moyen de s'assurer que deux clients n'ont pas le même ID): - un identificateur de message (pour lier ensemble des segments de message). - un dernier drapeau (pour commencer le processus de reconstruction). - un segment de taille limitée (par exemple, 1M).

2/Compression.

Puisque XML est du texte, il est mûr pour la compression. Les bibliothèques 7zip sont les meilleures que j'ai vues en termes de réduction de taille. Si cela serait assez rapide est une autre question.

3/ Correction possible en modifiant le Registre.

Consultez la zone de registre HKLM/Software/Microsoft/Rpc pour la clé RpcMaxSize. Il y a quelques sites que j'ai googlé qui suggèrent de régler ceci à -1 pour supprimer les limitations de taille (globalement, alors faites attention).

4/Correction lors de l'enregistrement de votre interface.

Vous pouvez apparemment obtenir le même effet que (3) sur une interface spécifique avec RpcServerRegisterIf2().

+0

actuelle La raison en est que nous envoyons une représentation XML d'objets énormes et ne veulent pas penser à l'optimiser (mais c'est certainement possible). Donc, s'il existe un moyen simple de contourner le problème, ce serait très pratique. – sharptooth

+0

Eh bien, la segmentation est une possibilité: limitez vos paramètres à un ID de session, un dernier indicateur et (par exemple) 1M de texte. Vous devrez segmenter votre code XML à la source et le reconstituer à la destination. Pas mon premier choix mais une solution rapide et sale qui devrait fonctionner avec un minimum d'effort. – paxdiablo

+0

Oui, cela fonctionnerait et c'est facile, mais une solution sans effort (le cas échéant) serait plus pratique. Lazyness, vous savez ... – sharptooth

1

La taille de chaque appel RPC dans son ensemble est généralement limité par divers facteurs tels que les limites de transport (ex: taille de paquet sur UDP, le débit binaire/temps d'attente maximum)

Ce que vous pouvez faire est de diviser votre chaîne dans des paquets et l'envoyer avec plusieurs appels,

ou ouvrir une prise supplémentaire tcp pour envoyer vos données et contrôler avec votre RPC

+0

RPC a une bonne méthode pour envoyer d'énormes tableaux de données appelés "pipe". Le problème est que nous avons essayé d'y passer et que nous l'avons vu se comporter bizarrement - http://stackoverflow.com/questions/684625/already-listening-wh-invoking-an-rpc-call – sharptooth

Questions connexes