Remoting и Delegate в очередной раз
От: wraithik Россия  
Дата: 12.10.05 19:32
Оценка:
Заранее просьба не пинать тему. Поиском пользоватлся.

Вообщем есть объект с событием, есть сервер (консоль, где этот объет крутится) и клиент (форма, которая конектися к клиенту).
У формы есть метод, который надо прицепить не событие удаленного объекта. CallBack'и работают на 100%, все проверено.

Подключаюсь к удаленному объекту:
host = (MyObject)RemotingServices.Connect(...)
пытаюсь подключить делегата:
host.strChanged +=new EventHandler(OnStrChanged)
метод OnStrChanged определен как public в форме.
В этот момент у меня вываливается сообщение: что-то там не доступно. Т.е. сервер не может подгрузить клиентскую сборку (Client.exe), т.к. переносом ее в каталог червера проблема решается.

Возникла идея, а что если сделать интерфейс (записхнуть его в общую сборку, туда где объект валяется):
public interfcae MyInterface {
void OnStrChange(object sender, EvantArgs e);
}

класс формы сдлеать поодерживающим интрефейс MyInterface
public class Form1 : Form, MyInterface {

...

void MyInterface.OnStrChange(object sender, EvantArgs e)
{
...
}

}

это я все сделал, но как подцепиць метод интерфейса (чтобы сервер не искал клиентскую сборку) к событию, конструкция вида:
host.strChanged +=new EventHandler(MyInterface.OnStrChanged)
не работает уже на стадии компиляции

может кто знает как решать проблему.
Re: Remoting и Delegate в очередной раз
От: mamoNT2005  
Дата: 12.10.05 19:50
Оценка: +2
Здравствуйте, wraithik, Вы писали:

W>может кто знает как решать проблему.


Избавиться от необходимости иметь клиентскую сборку на сервере можно так:
в общей сборке создать класс, который будет ретранслировать через себя события, возникающие на сервере. Например так:


    public class EventRepeater
        : MarshalByRefObject
    {
        public override object InitializeLifetimeService() // Не забываем
        {
            return null;
        }

        public event EventHandler SmthChanged;
        public void OnSmthChanged()
        {
            if (SmthChanged != null)
                SmthChanged();
        }
    }


Теперь клиент подписывается не напрямую к серверу, а через репитера.


EventRepeater rep = new EventRepeater ();
server.SmthChanged += new EventHandler (rep.OnSmthChanged);
rep.SmthChanged += new EventHandler (this.ClientMethod)


То есть сначала подписывает репитра к серверу, а потом себя к репитеру. Поскольку EventRepeater находится в общей сборке, клиентская сборка серверу больше не нужна
Re[2]: Remoting и Delegate в очередной раз
От: wraithik Россия  
Дата: 12.10.05 19:59
Оценка:
Здравствуйте, mamoNT2005, Вы писали:

NT>Здравствуйте, wraithik, Вы писали:


W>>может кто знает как решать проблему.


NT>Избавиться от необходимости иметь клиентскую сборку на сервере можно так:

NT>в общей сборке создать класс, который будет ретранслировать через себя события, возникающие на сервере. Например так:


NT>
NT>    public class EventRepeater
NT>        : MarshalByRefObject
NT>    {
NT>        public override object InitializeLifetimeService() // Не забываем
NT>        {
NT>            return null;
NT>        }

NT>        public event EventHandler SmthChanged;
NT>        public void OnSmthChanged()
NT>        {
NT>            if (SmthChanged != null)
NT>                SmthChanged();
NT>        }
NT>    }
NT>


NT>Теперь клиент подписывается не напрямую к серверу, а через репитера.



NT>
NT>EventRepeater rep = new EventRepeater ();
NT>server.SmthChanged += new EventHandler (rep.OnSmthChanged);
NT>rep.SmthChanged += new EventHandler (this.ClientMethod)
NT>


NT>То есть сначала подписывает репитра к серверу, а потом себя к репитеру. Поскольку EventRepeater находится в общей сборке, клиентская сборка серверу больше не нужна


Спасибо. Этот способ я знал.
Походу больше никак. Жаль.
Re[3]: Remoting и Delegate в очередной раз
От: xexe2  
Дата: 13.10.05 06:50
Оценка:
делаешь класс и кидаешь его в сборку которую знает и сервер и клиент
(обычно та где храниться интерфес удаленного объекта ну или сам объект егоего юзают без интерфейса)

public abstract class DelegatableObject : MarshalByRefObject

{
    public override object InitializeLifetimeService()
    {
        return null;
    }
    public void Callback()
    {
        InternalCallback();
    }
    protected abstract void InternalCallback();
}


далее на клиенте создаешь класс и наследуешь его от DelegatableObject
ну и создаешь экземпляр и


IServer.Update += new FooDelegate(fooDelegateAbleObject.Callback);
ну вроде и все:)
Re: Remoting и Delegate в очередной раз
От: oleksab Украина  
Дата: 13.10.05 09:20
Оценка:
Здравствуйте, wraithik, Вы писали:

W>У формы есть метод, который надо прицепить не событие удаленного объекта. CallBack'и работают на 100%, все проверено.


Можно для каждого объекта, требующего уведомления от сервера, создавать прокси (унаследованный от MBR). Этот прокси должен реализовать какой-нибуть IProxy, в котором будет простой метод
Notify(NotificationType nt, object o) — здесь нужно будет сделать всю реальную работу по уведомлению клиента.
На сервере — методы Subscribe, добавляющие подписчика (IProxy) в коллекцию и удаляющие его. При необходимости уведомить — перебираем коллекцию и вызываем методы удаленного объекта. В данном случае, клиент и сервер меняются местами и сервер начинает вызывать методы объекта на клиенте. Ну а на клиенте можно делать все, что угодно. При такой схеме, если клиент отвалится, то вылетит исключение и можно будет отписать клиента.
... << RSDN@Home 1.2.0 alpha rev. 0>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.