public void HandleData(MemBlock payload, ISender ret_path, object state)
{
Exception exception = null;
#if RPC_DEBUG
Console.Error.WriteLine("[RpcServer: {0}] Getting method invocation request at: {1}.",
_rrman.Info, DateTime.Now);
#endif
try {
object data = AdrConverter.Deserialize(payload);
IList l = data as IList;
if( l == null ) {
//We could not cast the request into a list... so sad:
throw new AdrException(-32600,"method call not a list");
}
string methname = (string)l[0];
#if RPC_DEBUG
Console.Error.WriteLine("[RpcServer: {0}] Getting invocation request, method: {1}",
_rrman.Info, methname);
#endif
/*
* Lookup this method name in our table.
* This uses a cache, so it should be fast
* after the first time
*/
IRpcHandler handler = null;
string mname = null;
lock( _sync ) {
object[] info = (object[]) _method_cache[methname];
if( info == null ) {
int dot_idx = methname.IndexOf('.');
if( dot_idx == -1 ) {
throw new AdrException(-32601, "No Handler for method: " + methname);
}
string hname = methname.Substring(0, dot_idx);
//Skip the '.':
mname = methname.Substring(dot_idx + 1);
handler = (IRpcHandler)_method_handlers[ hname ];
if( handler == null ) {
//No handler for this.
throw new AdrException(-32601, "No Handler for method: " + methname);
}
info = new object[2];
info[0] = handler;
info[1] = mname;
_method_cache[ methname ] = info;
}
else {
handler = (IRpcHandler)info[0];
mname = (string)info[1];
}
}
ArrayList pa = (ArrayList)l[1];
handler.HandleRpc(ret_path, mname, pa, ret_path);
}
catch(ArgumentException argx) {
exception = new AdrException(-32602, argx);
}
catch(TargetParameterCountException argx) {
exception = new AdrException(-32602, argx);
}
catch(Exception x) {
exception = x;
}
if (exception != null) {
//something failed even before invocation began
#if RPC_DEBUG
Console.Error.WriteLine("[RpcServer: {0}] Something failed even before invocation began: {1}",
_rrman.Info, exception);
#endif
using( MemoryStream ms = new MemoryStream() ) {
AdrConverter.Serialize(exception, ms);
ret_path.Send( new CopyList( PType.Protocol.Rpc, MemBlock.Reference( ms.ToArray() ) ) );
}
}
}