| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- //
- // System.Runtime.Remoting.RemotingServices.cs
- //
- // Authors:
- // Dietmar Maurer ([email protected])
- // Lluis Sanchez Gual ([email protected])
- // Patrik Torstensson
- //
- // (C) 2001 Ximian, Inc. http://www.ximian.com
- //
- using System;
- using System.Reflection;
- using System.Threading;
- using System.Collections;
- using System.Runtime.Remoting.Messaging;
- using System.Runtime.Remoting.Proxies;
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Contexts;
- using System.Runtime.Remoting.Activation;
- using System.Runtime.Remoting.Lifetime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.IO;
- namespace System.Runtime.Remoting
- {
- public sealed class RemotingServices
- {
- // Holds the identities of the objects, using uri as index
- static Hashtable uri_hash = new Hashtable ();
- internal static string app_id;
- static int next_id = 1;
-
- static RemotingServices ()
- {
- RegisterInternalChannels ();
- app_id = "/" + Guid.NewGuid().ToString().Replace('-', '_') + "/";
- CreateWellKnownServerIdentity (typeof(RemoteActivator), "RemoteActivationService.rem", WellKnownObjectMode.Singleton);
- }
-
- private RemotingServices () {}
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static object InternalExecute (MonoMethod method, Object obj,
- Object[] parameters, out object [] out_args);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern static bool IsTransparentProxy (object proxy);
-
- internal static IMethodReturnMessage InternalExecuteMessage (
- MarshalByRefObject target, IMethodCallMessage reqMsg)
- {
- ReturnMessage result;
-
- MonoMethod method = (MonoMethod) target.GetType().GetMethod(reqMsg.MethodName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance, null, (Type[]) reqMsg.MethodSignature, null);
- try {
- object [] out_args;
- object rval = InternalExecute (method, target, reqMsg.Args, out out_args);
- result = new ReturnMessage (rval, out_args, out_args.Length,
- reqMsg.LogicalCallContext, reqMsg);
-
- } catch (Exception e) {
- result = new ReturnMessage (e, reqMsg);
- }
- return result;
- }
- public static IMethodReturnMessage ExecuteMessage (
- MarshalByRefObject target, IMethodCallMessage reqMsg)
- {
- if (IsTransparentProxy(target))
- {
- // Message must go through all chain of sinks
- RealProxy rp = GetRealProxy (target);
- return (IMethodReturnMessage) rp.Invoke (reqMsg);
- }
- else // Direct call
- return InternalExecuteMessage (target, reqMsg);
- }
- public static object Connect (Type classToProxy, string url)
- {
- ObjRef objRef = new ObjRef (classToProxy, url, null);
- return GetRemoteObject (objRef, classToProxy);
- }
- public static object Connect (Type classToProxy, string url, object data)
- {
- ObjRef objRef = new ObjRef (classToProxy, url, data);
- return GetRemoteObject (objRef, classToProxy);
- }
- public static bool Disconnect (MarshalByRefObject obj)
- {
- if (obj == null) throw new ArgumentNullException ("obj");
- if (IsTransparentProxy (obj)) throw new ArgumentException ("The obj parameter is a proxy");
- ServerIdentity identity = obj.ObjectIdentity;
- if (identity == null || !identity.IsConnected)
- return false;
- else
- {
- LifetimeServices.StopTrackingLifetime (identity);
- DisposeIdentity (identity);
- return true;
- }
- }
- public static Type GetServerTypeForUri (string uri)
- {
- Identity ident = GetIdentityForUri (uri);
- if (ident == null) return null;
- return ident.ObjectType;
- }
- public static string GetObjectUri (MarshalByRefObject obj)
- {
- Identity ident = GetObjectIdentity(obj);
- if (ident != null) return ident.ObjectUri;
- else return null;
- }
- public static object Unmarshal (ObjRef objref)
- {
- return Unmarshal(objref, true);
- }
- public static object Unmarshal (ObjRef objref, bool fRefine)
- {
- // FIXME: use type name when fRefine==true
- Type classToProxy = fRefine ? objref.ServerType : typeof (MarshalByRefObject);
- if (objref.IsReferenceToWellKnow)
- return GetRemoteObject(objref, classToProxy);
- else
- {
- if (classToProxy.IsContextful)
- {
- // Look for a ProxyAttribute
- ProxyAttribute att = (ProxyAttribute) Attribute.GetCustomAttribute (classToProxy, typeof(ProxyAttribute),true);
- if (att != null)
- return att.CreateProxy (objref, classToProxy, null, null).GetTransparentProxy();
- }
- return GetProxyForRemoteObject (objref, classToProxy);
- }
- }
- public static ObjRef Marshal (MarshalByRefObject obj)
- {
- return Marshal (obj, null, null);
- }
-
- public static ObjRef Marshal (MarshalByRefObject obj, string uri)
- {
- return Marshal (obj, uri, null);
- }
-
- public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
- {
- if (IsTransparentProxy (obj))
- {
- RealProxy proxy = RemotingServices.GetRealProxy(obj);
- Identity identity = proxy.ObjectIdentity;
- if (identity != null)
- {
- if (identity.ObjectType.IsContextful && !identity.IsConnected)
- {
- // Unregistered local contextbound object. Register now.
- ClientActivatedIdentity cboundIdentity = (ClientActivatedIdentity)identity;
- if (uri == null) uri = NewUri();
- cboundIdentity.ObjectUri = uri;
- RegisterServerIdentity (cboundIdentity);
- cboundIdentity.StartTrackingLifetime ((ILease)obj.InitializeLifetimeService());
- return cboundIdentity.CreateObjRef(requested_type);
- }
- else if (uri != null)
- throw new RemotingException ("It is not possible marshal a proxy of a remote object");
- return proxy.ObjectIdentity.CreateObjRef(requested_type);
- }
- }
- if (requested_type == null) requested_type = obj.GetType();
- if (uri == null)
- {
- uri = NewUri();
- CreateClientActivatedServerIdentity (obj, requested_type, uri);
- }
- else
- {
- ClientActivatedIdentity identity = uri_hash [uri] as ClientActivatedIdentity;
- if (identity == null || obj != identity.GetServerObject())
- CreateClientActivatedServerIdentity (obj, requested_type, uri);
- }
- return obj.CreateObjRef(requested_type);
- }
- static string NewUri ()
- {
- return app_id + Environment.TickCount + "_" + next_id++;
- }
- public static RealProxy GetRealProxy (object proxy)
- {
- if (!IsTransparentProxy(proxy)) throw new RemotingException("Cannot get the real proxy from an object that is not a transparent proxy");
- return (RealProxy)((TransparentProxy)proxy)._rp;
- }
- public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
- {
- Type type = Type.GetType (msg.TypeName);
- if (type == null)
- throw new RemotingException ("Type '" + msg.TypeName + "' not found!");
- BindingFlags bflags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
- if (msg.MethodSignature == null)
- return type.GetMethod (msg.MethodName, bflags);
- else
- return type.GetMethod (msg.MethodName, bflags, null, (Type[]) msg.MethodSignature, null);
- }
- public static void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
- {
- if (obj == null) throw new ArgumentNullException ("obj");
- ObjRef oref = Marshal ((MarshalByRefObject)obj);
- oref.GetObjectData (info, context);
- }
- public static ObjRef GetObjRefForProxy(MarshalByRefObject obj)
- {
- Identity ident = GetObjectIdentity(obj);
- if (ident == null) return null;
- else return ident.CreateObjRef(null);
- }
- [MonoTODO]
- public static string GetSessionIdForMethodMessage(IMethodMessage msg)
- {
- throw new NotImplementedException ();
- }
- public static bool IsMethodOverloaded(IMethodMessage msg)
- {
- Type type = msg.MethodBase.DeclaringType;
- MemberInfo[] members = type.GetMember (msg.MethodName, MemberTypes.Method, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
- return members.Length > 1;
- }
- public static bool IsObjectOutOfAppDomain(object tp)
- {
- Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
- if (ident != null) return !ident.IsFromThisAppDomain;
- else return false;
- }
- public static bool IsObjectOutOfContext(object tp)
- {
- ServerIdentity ident = GetObjectIdentity((MarshalByRefObject)tp) as ServerIdentity;
- if (ident != null) return ident.Context != System.Threading.Thread.CurrentContext;
- else return false;
- }
- public static bool IsOneWay(MethodBase method)
- {
- object[] atts = method.GetCustomAttributes (typeof (OneWayAttribute), false);
- return atts.Length > 0;
- }
- public static void SetObjectUriForMarshal(MarshalByRefObject obj, string uri)
- {
- if (IsTransparentProxy (obj)) throw new RemotingException ("SetObjectUriForMarshal method should only be called for MarshalByRefObjects that exist in the current AppDomain.");
- Marshal (obj, uri);
- }
- #region Internal Methods
-
- internal static object CreateClientProxy (ActivatedClientTypeEntry entry, object[] activationAttributes)
- {
- if (entry.ContextAttributes != null || activationAttributes != null)
- {
- ArrayList props = new ArrayList ();
- if (entry.ContextAttributes != null) props.AddRange (entry.ContextAttributes);
- if (activationAttributes != null) props.AddRange (activationAttributes);
- return CreateClientProxy (entry.ObjectType, entry.ApplicationUrl, props.ToArray ());
- }
- else
- return CreateClientProxy (entry.ObjectType, entry.ApplicationUrl, null);
- }
-
- internal static object CreateClientProxy (Type objectType, string url, object[] activationAttributes)
- {
- string activationUrl = url + "/RemoteActivationService.rem";
- string objectUri;
- IMessageSink sink = GetClientChannelSinkChain (activationUrl, null, out objectUri);
- RemotingProxy proxy = new RemotingProxy (objectType, activationUrl, activationAttributes);
- return proxy.GetTransparentProxy();
- }
-
- internal static object CreateClientProxy (WellKnownClientTypeEntry entry)
- {
- return Connect (entry.ObjectType, entry.ObjectUrl, null);
- }
-
- internal static object CreateClientProxyForContextBound (Type type, object[] activationAttributes)
- {
- if (type.IsContextful)
- {
- // Look for a ProxyAttribute
- ProxyAttribute att = (ProxyAttribute) Attribute.GetCustomAttribute (type, typeof(ProxyAttribute), true);
- if (att != null)
- return att.CreateInstance (type);
- }
- RemotingProxy proxy = new RemotingProxy (type, ChannelServices.CrossContextUrl, activationAttributes);
- return proxy.GetTransparentProxy();
- }
-
- internal static Identity GetIdentityForUri (string uri)
- {
- lock (uri_hash)
- {
- return (Identity)uri_hash [uri];
- }
- }
- internal static Identity GetObjectIdentity (MarshalByRefObject obj)
- {
- if (IsTransparentProxy(obj))
- return GetRealProxy (obj).ObjectIdentity;
- else
- return obj.ObjectIdentity;
- }
- internal static ClientIdentity GetOrCreateClientIdentity(ObjRef objRef, Type proxyType)
- {
- // This method looks for an identity for the given url.
- // If an identity is not found, it creates the identity and
- // assigns it a proxy to the remote object.
- // Creates the client sink chain for the given url or channelData.
- // It will also get the object uri from the url.
- object channelData = objRef.ChannelInfo != null ? objRef.ChannelInfo.ChannelData : null;
- string url = (channelData == null) ? objRef.URI : null;
- string objectUri;
- IMessageSink sink = GetClientChannelSinkChain (url, channelData, out objectUri);
- if (objectUri == null) objectUri = objRef.URI;
- lock (uri_hash)
- {
- ClientIdentity identity = uri_hash [objRef.URI] as ClientIdentity;
- if (identity != null)
- return identity; // Object already registered
- // Creates an identity and a proxy for the remote object
- identity = new ClientIdentity (objectUri, objRef);
- identity.ChannelSink = sink;
- if (proxyType != null)
- {
- RemotingProxy proxy = new RemotingProxy (proxyType, identity);
- identity.ClientProxy = (MarshalByRefObject) proxy.GetTransparentProxy();
- }
- // Registers the identity
- uri_hash [objRef.URI] = identity;
- return identity;
- }
- }
- static IMessageSink GetClientChannelSinkChain(string url, object channelData, out string objectUri)
- {
- IMessageSink sink = ChannelServices.CreateClientChannelSinkChain (url, channelData, out objectUri);
- if (sink == null)
- {
- if (url != null)
- {
- string msg = String.Format ("Cannot create channel sink to connect to URL {0}. An appropriate channel has probably not been registered.", url);
- throw new RemotingException (msg);
- }
- else
- {
- string msg = String.Format ("Cannot create channel sink to connect to the remote object. An appropriate channel has probably not been registered.", url);
- throw new RemotingException (msg);
- }
- }
- return sink;
- }
- internal static ClientActivatedIdentity CreateContextBoundObjectIdentity(Type objectType)
- {
- ClientActivatedIdentity identity = new ClientActivatedIdentity (null, objectType);
- identity.ChannelSink = ChannelServices.CrossContextChannel;
- return identity;
- }
- internal static ClientActivatedIdentity CreateClientActivatedServerIdentity(MarshalByRefObject realObject, Type objectType, string objectUri)
- {
- ClientActivatedIdentity identity = new ClientActivatedIdentity (objectUri, objectType);
- identity.AttachServerObject (realObject, Context.DefaultContext);
- RegisterServerIdentity (identity);
- identity.StartTrackingLifetime ((ILease)realObject.InitializeLifetimeService ());
- return identity;
- }
- internal static ServerIdentity CreateWellKnownServerIdentity(Type objectType, string objectUri, WellKnownObjectMode mode)
- {
- ServerIdentity identity;
- if (mode == WellKnownObjectMode.SingleCall)
- identity = new SingleCallIdentity(objectUri, Context.DefaultContext, objectType);
- else
- identity = new SingletonIdentity(objectUri, Context.DefaultContext, objectType);
- RegisterServerIdentity (identity);
- return identity;
- }
- private static void RegisterServerIdentity(ServerIdentity identity)
- {
- lock (uri_hash)
- {
- if (uri_hash.ContainsKey (identity.ObjectUri))
- throw new RemotingException ("Uri already in use: " + identity.ObjectUri);
- uri_hash[identity.ObjectUri] = identity;
- }
- }
- internal static object GetProxyForRemoteObject (ObjRef objref, Type classToProxy)
- {
- ClientActivatedIdentity identity = uri_hash [objref.URI] as ClientActivatedIdentity;
- if (identity != null) return identity.GetServerObject ();
- else return GetRemoteObject (objref, classToProxy);
- }
- internal static object GetRemoteObject(ObjRef objRef, Type proxyType)
- {
- ClientIdentity id = GetOrCreateClientIdentity (objRef, proxyType);
- return id.ClientProxy;
- }
- internal static object GetDomainProxy(AppDomain domain)
- {
- byte[] data = null;
- Context currentContext = Thread.CurrentContext;
- AppDomain currentDomain = AppDomain.InternalSetDomain (domain);
- try
- {
- data = domain.GetMarshalledDomainObjRef ();
- }
- finally
- {
- AppDomain.InternalSetDomain (currentDomain);
- AppDomain.InternalSetContext (currentContext);
- }
- MemoryStream stream = new MemoryStream (data);
- ObjRef appref = (ObjRef) CADSerializer.DeserializeObject (stream);
- return (AppDomain) RemotingServices.Unmarshal(appref);
- }
- private static void RegisterInternalChannels()
- {
- CrossAppDomainChannel.RegisterCrossAppDomainChannel();
- }
-
- internal static void DisposeIdentity (ServerIdentity ident)
- {
- uri_hash.Remove (ident.ObjectUri);
- }
- internal static Identity GetMessageTargetIdentity (IMessage msg)
- {
- // Returns the identity where the message is sent
- if (msg is IInternalMessage)
- return ((IInternalMessage)msg).TargetIdentity;
- lock (uri_hash)
- {
- return uri_hash [((IMethodMessage)msg).Uri] as ServerIdentity;
- }
- }
- internal static void SetMessageTargetIdentity (IMessage msg, Identity ident)
- {
- if (msg is IInternalMessage)
- ((IInternalMessage)msg).TargetIdentity = ident;
- }
- #endregion
- }
- }
|