Здравствуйте все.
Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы.
Но не так:
IRemoteObj robj = (IRemoteObj) (new MyRealProxy(typeof(IRemoteObj)).GetTransparentProxy());
Потому что клиента менять не хочется.
Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере.
Это логично, так как атрибут применен для класса, который на только на сервере.
Заранее спасибо.
Здравствуйте, Maxeemus, Вы писали:
M>Здравствуйте все. M>Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы.
Какой тип активации?
M>Но не так: M>
M> IRemoteObj robj = (IRemoteObj) (new MyRealProxy(typeof(IRemoteObj)).GetTransparentProxy());
M>
M>Потому что клиента менять не хочется. M>Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере. M>Это логично, так как атрибут применен для класса, который на только на сервере.
Как получаешь ссылку на серверный объект на клиенте?
ИМХО, это не логично. Прокси создаеться на клиенте в любом случае.
Посмотри пример здесь
У RemoteClass должен подмениться RealProxy, если у него установлен атрибут ProxyAttribute и он пронаследован от ContextBoundObject. У тебя даже тут не подменяеться?
M>далее все объекты получаем через него. Например: M>
M>У RemoteClass должен подмениться RealProxy, если у него установлен атрибут ProxyAttribute и он пронаследован от ContextBoundObject. У тебя даже тут не подменяеться?
M>>далее все объекты получаем через него. Например: M>>
M>>Хочется что бы у всех объектов на клиенте подменялся RealProxy
M>чтобы у some_obj подменялось нужно у них соответственно тоже установить атрибут ProxyAttribute и пронаследовать от ContextBoundObject
M>Запость текст своего прокси. Тип прокси доступе на клиенте?
. Спасибо. На клиенте доступен и ProxyAttribute и RealProxy и ТОЛЬКО интерфейсы реализуемые объектом. Так в этом случае возникает ошибка: System.IO.FileNotFoundException: File or assembly name Server, or one of its dependencies, was not found.
File name: "Server"
Видимо где-то на клиенте попытка работать с типами сервеных объектов.
. Спасибо. На клиенте доступен и ProxyAttribute и RealProxy и ТОЛЬКО интерфейсы реализуемые объектом. Так в этом случае возникает ошибка: M>System.IO.FileNotFoundException: File or assembly name Server, or one of its dependencies, was not found. M>File name: "Server"
У тебя на стороне клиента вызываеться
public override MarshalByRefObject CreateInstance(Type serverType)
какой тип передаеться? Или даже до этого не доходит? На стороне сервера этот метод тоже зовется, но там нужно возвращать base.CreateInstance, а не свой proxy.
Перекрой CreateProxy и посмотри что туда передаеться.
Сейчас сам проверить не могу.
Здравствуйте, Maxeemus, Вы писали:
M>Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы.
Если не секрет, то какие цели приследуются в замене RealProxy?
Чем тот-же "дипломатический" приемник не подошел?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, Maxeemus, Вы писали:
M>>Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы.
TK>Если не секрет, то какие цели приследуются в замене RealProxy? TK>Чем тот-же "дипломатический" приемник не подошел?
Попытка отследить момент когда ссылка на TransparentProxy больше не нужна на клиенте.
Я предположил, что время жизни RealProxy и TransparentProxy примерно одинаково. Т.е. нет ссылок на TransparentProxy — нет и на RealProxy. А в RealProxy мы можем написать свой деструктор и соответственно отследить его вызов.
. Спасибо. На клиенте доступен и ProxyAttribute и RealProxy и ТОЛЬКО интерфейсы реализуемые объектом. Так в этом случае возникает ошибка: M>>System.IO.FileNotFoundException: File or assembly name Server, or one of its dependencies, was not found. M>>File name: "Server" M>У тебя на стороне клиента вызываеться M> public override MarshalByRefObject CreateInstance(Type serverType) M>какой тип передаеться? Или даже до этого не доходит? На стороне сервера этот метод тоже зовется, но там нужно возвращать base.CreateInstance, а не свой proxy. M>Перекрой CreateProxy и посмотри что туда передаеться. M>Сейчас сам проверить не могу.
В том то и дело, что на клиенте CreateInstance даже не вызываеться. Я смотрел AppDomain.CurrentDomain.FriendlyName — только сервер.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Maxeemus, Вы писали:
M>>Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере.
AVK> RealProxy подменяется только на клиенте, на сервере объект работает напрямую с ченнелом.
RealProxy и на сервере и на клиенте создаеться.
Это TransparentProxy только на клиенте.
RealProxy.Invoke вызываеться на клиенте, но перед вызовом Invoke вот такой Exception: System.IO.FileNotFoundException: File or assembly name Server, or one of its dependencies, was not found.
File name: "Server"
Server stack trace:
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Remoting.RemotingServices.GetOrCreateProxy(Identity idObj, Object proxy, Boolean fRefine)
at System.Runtime.Remoting.RemotingServices.InternalUnmarshal(ObjRef objectRef, Object proxy, Boolean fRefine)
at System.Runtime.Remoting.ObjRef.GetRealObjectHelper()
at System.Runtime.Remoting.ObjRef.GetRealObject(StreamingContext context)
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Common.IRemote.GetRemoteData()
at Client.Form1.Create_Click(Object sender, EventArgs e) in d:\data\sponsortest\client\clientform.cs:line 128
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
На клиенте доступны только интерфейсы а не сам класс.
Здравствуйте, Maxeemus, Вы писали:
M>>>Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере.
AVK>> RealProxy подменяется только на клиенте, на сервере объект работает напрямую с ченнелом.
M>RealProxy и на сервере и на клиенте создаеться.
Смотря что понимать под клиентом и сервером. Если Под клиентом понимать контекст(домен) с объектом, а под клиентом другой контекст/домен то RealProxy всегда создается в контексте/домене клиента. Если попытаться опубликовать в ремоутинге объект из другого контекста, то в данной ситуации серверный ченнел ремоутинга будет являться клиентом для объекта с ProxyAttribute.
Здравствуйте, Maxeemus, Вы писали:
TK>>Если не секрет, то какие цели приследуются в замене RealProxy? TK>>Чем тот-же "дипломатический" приемник не подошел?
M>Попытка отследить момент когда ссылка на TransparentProxy больше не нужна на клиенте. M>Я предположил, что время жизни RealProxy и TransparentProxy примерно одинаково. Т.е. нет ссылок на TransparentProxy — нет и на RealProxy. А в RealProxy мы можем написать свой деструктор и соответственно отследить его вызов.
Чем тот-же "дипломатический" приемник не подошел?
PS
А зачем такое надо-то?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Maxeemus, Вы писали:
M>Здравствуйте все. M>Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы. M>Но не так: M>
M> IRemoteObj robj = (IRemoteObj) (new MyRealProxy(typeof(IRemoteObj)).GetTransparentProxy());
M>
M>Потому что клиента менять не хочется. M>Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере. M>Это логично, так как атрибут применен для класса, который на только на сервере. M>Заранее спасибо.
Не знаю, актуально ли для Вас данная проблема.
Но тем не менее я решил написать, как решил ее я.
Существует два способа создания реального прокси:
— атрибут
— код, наподобие этого:
1-й способ влечет за собой активацию кода атрибута и в случае, когда объект создается в серверном процессе для "собственных нужд". Кроме того, атрибуты работают (если я правильно понял) только для конструкций типа "new QQQ" или "Activator.GetObject". При передаче по ссылке оно на клиенте не работает.
Отсюда можно сделать вывод, что нужно использовать 2-й способ. Ну а чтобы не городить код создания прокси постоянно, я сделал так:
Сделал для своего активатора объектов прокси, в котором есть вот такая ф-ция Invoke (правда она предназначена только для ф-ций типа IQQQ GetInterface() ):
public override IMessage Invoke(IMessage msg)
{
// сначала обработаем запрос...
IMessage retMsg = m_OldRProxy.Invoke(msg);
Object retValue;
// мы поддерживаем этот интерфейс?if (retMsg is IMethodReturnMessage)
{
IMethodReturnMessage mrm = (IMethodReturnMessage)retMsg;
retValue = mrm.ReturnValue;
// может быть, результат - прозрачное проксиif (RemotingServices.IsTransparentProxy(retValue))
{
// получим тип возвращаемого объекта...
Type typeCurObject = Type.GetType(mrm.TypeName);
// рассматриваем только методы без параметров, возвращающие интерфейс
MethodInfo methodInfo = typeCurObject.GetMethod(mrm.MethodName, new Type[0]);
ServerObjProxy newProxy = new ServerObjProxy(methodInfo.ReturnType, (MarshalByRefObject)retValue);
ReturnMessage returnMessage = new ReturnMessage(newProxy.GetTransparentProxy(), mrm.OutArgs, mrm.OutArgCount,
mrm.LogicalCallContext, (IMethodCallMessage)msg);
return returnMessage;
}
}
return retMsg;
}