static private SyncProcessMessageCallback ( Object args ) : Object | ||
args | Object | |
return | Object |
internal static Object SyncProcessMessageCallback(Object[] args)
{
IMessage reqMsg = args[0] as IMessage;
Context srvCtx = args[1] as Context;
IMessage replyMsg = null;
// If profiling of remoting is active, must tell the profiler that we have received
// a message.
if (RemotingServices.CORProfilerTrackRemoting())
{
Guid g = Guid.Empty;
if (RemotingServices.CORProfilerTrackRemotingCookie())
{
Object obj = reqMsg.Properties["CORProfilerCookie"];
if (obj != null)
{
g = (Guid) obj;
}
}
RemotingServices.CORProfilerRemotingServerReceivingMessage(g, false);
}
Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");
// Server side notifications for dynamic sinks are done
// in the x-context channel ... this is to maintain
// symmetry of the point of notification between
// the client and server context
srvCtx.NotifyDynamicSinks(
reqMsg,
false, // bCliSide
true, // bStart
false, // bAsync
true); // bNotifyGlobals
replyMsg = srvCtx.GetServerContextChain().SyncProcessMessage(reqMsg);
srvCtx.NotifyDynamicSinks(
replyMsg,
false, // bCliSide
false, // bStart
false, // bAsync
true); // bNotifyGlobals
Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");
// If profiling of remoting is active, must tell the profiler that we are sending a
// reply message.
if (RemotingServices.CORProfilerTrackRemoting())
{
Guid g;
RemotingServices.CORProfilerRemotingServerSendingReply(out g, false);
if (RemotingServices.CORProfilerTrackRemotingCookie())
{
replyMsg.Properties["CORProfilerCookie"] = g;
}
}
return replyMsg;
}
public static ServerProcessing DispatchMessage( IServerChannelSinkStack sinkStack, IMessage msg, out IMessage replyMsg) { ServerProcessing processing = ServerProcessing.Complete; replyMsg = null; try { if (null == msg) { throw new ArgumentNullException("msg"); } BCLDebug.Trace("REMOTE", "Dispatching for URI " + InternalSink.GetURI(msg)); // we must switch to the target context of the object and call the context chains etc... // Currenly XContextChannel does exactly so. So this method is just a wrapper.. // Make sure that incoming calls are counted as a remote call. This way it // makes more sense on a server. IncrementRemoteCalls(); // Check if the object has been disconnected or if it is // a well known object then we have to create it lazily. ServerIdentity srvId = CheckDisconnectedOrCreateWellKnownObject(msg); // Make sure that this isn't an AppDomain object since we don't allow // calls to the AppDomain from out of process (and x-process calls // are always dispatched through this method) if (srvId.ServerType == typeof(System.AppDomain)) { throw new RemotingException( Environment.GetResourceString( "Remoting_AppDomainsCantBeCalledRemotely")); } IMethodCallMessage mcm = msg as IMethodCallMessage; if (mcm == null) { // It's a plain IMessage, so just check to make sure that the // target object implements IMessageSink and dispatch synchronously. if (!typeof(IMessageSink).IsAssignableFrom(srvId.ServerType)) { throw new RemotingException( Environment.GetResourceString( "Remoting_AppDomainsCantBeCalledRemotely")); } processing = ServerProcessing.Complete; replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg); } else { // It's an IMethodCallMessage. // Check if the method is one way. Dispatch one way calls in // an asynchronous manner MethodInfo method = (MethodInfo)mcm.MethodBase; // X-process / X-machine calls should be to non-static // public methods only! Non-public or static methods can't // be called remotely. if (!IsMethodReallyPublic(method) && !RemotingServices.IsMethodAllowedRemotely(method)) { throw new RemotingException( Environment.GetResourceString( "Remoting_NonPublicOrStaticCantBeCalledRemotely")); } RemotingMethodCachedData cache = (RemotingMethodCachedData) InternalRemotingServices.GetReflectionCachedData(method); /* * FUTURE: * Dispatching asynchronously was cut from v1. We should reactivate * the following code in v1.x or v2. * * // look for async method version * MethodInfo begin; * MethodInfo end; * ServerChannelSinkStack serverSinkStack = sinkStack as ServerChannelSinkStack; * if ((sinkStack != null) && * cache.GetAsyncMethodVersion(out begin, out end)) * { * processing = ServerProcessing.Async; * IMessage asyncMsg = * new AsyncMethodCallMessageWrapper( * (IMethodCallMessage)msg, * begin, * new AsyncCallback(sinkStack.ServerCallback), * null); * serverSinkStack.AsyncMessage = asyncMsg; * serverSinkStack.AsyncEnd = end; * serverSinkStack.Message = (IMethodCallMessage)msg; * asyncMsg.Properties["__SinkStack"] = sinkStack; * * // We don't dispatch yet. That happens when the server transport sink * // eventually calls sinkStack.StoreAndDispatch(...). * } * else */ if (RemotingServices.IsOneWay(method)) { processing = ServerProcessing.OneWay; ChannelServices.GetCrossContextChannelSink().AsyncProcessMessage(msg, null); } else { // regular processing processing = ServerProcessing.Complete; if (!srvId.ServerType.IsContextful) { Object[] args = new Object[] { msg, srvId.ServerContext }; replyMsg = (IMessage)CrossContextChannel.SyncProcessMessageCallback(args); } else { replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg); } } } // end of case for IMethodCallMessage } catch (Exception e) { if (processing != ServerProcessing.OneWay) { try { IMethodCallMessage mcm = (IMethodCallMessage)((msg != null)?msg:new ErrorMessage()); replyMsg = (IMessage) new ReturnMessage(e, mcm); if (msg != null) { ((ReturnMessage)replyMsg).SetLogicalCallContext( (LogicalCallContext) msg.Properties[Message.CallContextKey]); } } catch (Exception) { // Fatal exception .. ignore } } } return(processing); } // DispatchMessage