tags:

views:

219

answers:

2

I have a program that uses Microsoft RPC for interprocess communication. When a call of a method with [in, string] parameter like this (MIDL notation):

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

is invoked it is usually successful. But if the parameter string is long enough (more than about 3 million characters) the call fails with RPC_S_CALL_FAILED_DNE ("The remote procedure call failed and did not execute."). It surely depends on the string length. The same call in the same conditions always succeeds if the string is within limit and always fails if the string is longer. It also looks like the limit is system- or machine-dependent.

Has anyone observed such behaviour and what is the possible solution (without shortening the parameter)?

+1  A: 

I've observed that message before but I don't think it was the same cause - the "did not execute" is a generic RPC error which can be caused by many things.

In our particular case, it was because we were hammering WMI too hard and not cleaning up our objects. But it appears to be a different cause in your case.

I know you said you didn't want to shorten the parameter but that may be the only way forward for you. I'm having a hard time visualizing the circumstances under which you need to send 6M across an RPC call. Perhaps if you explain the reasons behind it, we can help further.

Other possibilities based on comments to date:

1/ Segmentation.

Have the RPC calls limit the amount of data that travels across the wire. This could be done by segmenting the message at the source and reconstructing it at the destination, such as having three parameters (you could have the server dole out message identifiers in another RPC call or find some other way to ensure no two clients have the same ID): - a message identifier (for tying message segments together). - a last flag (to begin the reconstruction process). - a limited size segment (e.g., 1M).

2/ Compression.

Since XML is text, it's ripe for compression. The 7zip libraries are the best I've seen in terms of size reduction. Whether this would be fast enough is another matter.

3/ Possible fix by changing the registry.

Check out the HKLM/Software/Microsoft/Rpc registry area for the RpcMaxSize key. There are a couple of sites I've googled that suggest setting this to -1 will remove size limitations (globally, so be careful).

4/ Possible fix while registering your interface.

You can apparently achieve the same effect as (3) on a specific interface with RpcServerRegisterIf2().

paxdiablo
The reason is that we send an XML representation of huge objects and don't want to think of optimizing it (but it's definitely possible). So if there's a simple way to just bypass the problem it would be very handy.
sharptooth
Well, segmenting is one possibility: limit your parameters to a session-id, last-flag and (e.g.) 1M of text. You'll have to segment your XML at the source and piece it back together at the destination. Not my first choice but a quick and dirty solution that should work with minimal effort.
paxdiablo
Yes, this would work and it's easy but a zero-effort solution (if any) would be more handy. Lazyness, you know...
sharptooth
+1  A: 

The size of each RPC call as a whole is usually limited by various factors such as transport limits ( ex : packet size on UDP , bit rate / maximum latency )

What you can do is to split your string in packets and send it with multiple calls,

or open an additional tcp socket to send your data and control it with your current RPC

fa.
RPC has a nice method of sending huge arrays of data called "pipe". The problem is we tried to switch to it and saw it behaves strangely - http://stackoverflow.com/questions/684625/already-listening-when-invoking-an-rpc-call
sharptooth