Удалённый объект – объект с событиями. Компонент csSqw_Dll (SqwComp), Удап.объектcsSqw_RemObject_Dll (RemObj),сервер(SqwModels),клиент(SqwMain)
Компонент csSqw_Dll (SqwComp), Удап.объектcsSqw_RemObject_Dll (RemObj),сервер(SqwModels),клиент(SqwMain)
Последовательность разработки сервера и клиента:
1) Создать библиотеку csSqw_Dll с компонентом SqwComp. Подсоединить (Project/Add Reference) к ней библиотеку System.Drawing.dll, содержащую используемый класс Point.
Выполнить команду Build/Build Solution.
2) Создать библиотеку csSqw_RemObj_Dll с удалённым объектом RemObj, его интерфейсом IRemObj и классом RemObjEventArgs данных события. Подсоединить (Project/Add Reference) к ней библиотеку System.Runtime.Remoting.dll, содержащую класс MarshalByRefObject
Выполнить команду Build/Build Solution.
3) Создать консольное приложение csSqw_Server, подключив к нему библиотеки System.Runtime.Remoting.dll, System.Windows.Forms, System.Drawing, csSqw_Dll.dll, csSqw_RemObject_Dll.dll.
Выполнить команды Build/Build Solution и Debug/ Start Without Debugging.
Появится прикладное и консольное окно сервера. После запуска клиента в этом окне будут отображаться добавляемые в контейнер компоненты (квадраты синего цвета с красными номерами соответствующих компонентов).
4) Создать консольное приложение csSqw_Client, подключив к нему библиотеки System.Runtime.Remoting.dll, System.Windows.Forms, System.Drawing, csSqw_RemObject_Dll.dll.
Выполнить команды Build/Build Solution и Debug/ Start Without Debugging.
Появится прикладное и консольное окно клиента с двумя кнопками и элементом списка. Используя кнопки возможно добавление и удаление компонентов в контейнер сервера. Добавленные компоненты будут отображаться в прикладном окне сервера (квадраты синего цвета с красными номерами соответствующих компонентов).
5) Можно создать ещё одно приложение-клиент и осуществлять добавление и удаление компонентов на сервере из двух клиентов. Желательно модифицировать эту программу, введя удалённое событие, которое позволило во время модифицировать списки во всех клиентах.
/////////////////////////
// C# File csSqw_Dll Компонент
// Подключить (Project/AddReference) System.Drawing.dll
using System;
using System.Drawing;
using System.ComponentModel;
namespace csSqw_Dll
{
// Класс компонента SqwComp
public class SqwComp: Component // Класс компонента
{
private int numComp; // Номер компонента
private Point point; // Координаты компонента
// Конструктор
public SqwComp (int NumComp, Point Pnt)
{
numComp= NumComp;
point= Pnt;
}
// Свойство Number - номер компонента
public int Number
{
get
{
return numComp;
}
}
// Свойство Point - координаты компонента
public Point Point
{
get
{
return point;
}
}
}
}
/////////////////////////
// C# File csSqw_RemObj_Dll Удалённый объект
// Подсоединить (Project/Add Reference) System.Runtime.Remoting.dll
using System;
using System.Collections;
namespace csSqw_RemObject_Dll
{
// Класс объекта данных события evToCont из удалённого объекта
public class RemObjEventArgs: EventArgs
{
public string command; // Имя функции
public int number; // Номер компонента
public RemObjEventArgs (string S, int N)
{command= S; number= N;}
}
// Интерфейс удалённого объекта RemObj
public interface IRemObj
{
void CreateAdd ( ); // Создать компонент
void Remove (int num); // Удалить компонент с номером num
ArrayList GetList ( ); // Возвратить список номеров
void GetRef (ref ArrayList aL); // Получить список номеров
}
// Тип делегата события evToCont удалённого объекта
public delegate void FromRemObjToCont (RemObjEventArgs args,
ref ArrayList aL);
// Тип удалённого объекта
public class RemObj: MarshalByRefObject, IRemObj
{
public event FromRemObjToCont evToCont; // ссылка на событие
// Конструктор
public RemObj ( )
{
}
// Создать объект компонента и добавить в контейнер
public void CreateAdd ( )
{
if (evToCont != null)
{
RemObjEventArgs a= new RemObjEventArgs
("CreateAdd", 0);
ArrayList aL= null;
evToCont (a, ref aL);
}
}
// Удалить компонент из контейнера с указанным номером
public void Remove (int num)
{
if (evToCont != null)
{
RemObjEventArgs a= new RemObjEventArgs
("Remove", num);
ArrayList aL= null;
evToCont (a,ref aL);
}
}
// Возвратить список номеров компонентов в контейнере
public ArrayList GetList ( )
{
ArrayList aL= null;
if (evToCont != null)
{
RemObjEventArgs a= new RemObjEventArgs
("GetList", 0);
evToCont (a, ref aL);
}
return aL;
}
// Получить ссылку на список номеров компонентов в контейнере
public void GetRef (ref ArrayList AL)
{
ArrayList aL= null;
if (evToCont != null)
{
RemObjEventArgs a= new RemObjEventArgs
("GetList", 0);
evToCont (a, ref aL);
}
AL= aL;
}
}
}
/////////////////////////
// C# File csSqw_Server Сервер
// Подсоединить (Project/AddReference) csSqw_RemObject_Dll.dll
// Подсоединить (Project/AddReference) System.Runtime.Remoting.dll
// Подсоединить (Project/AddReference) csSqw_Dll.dll
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using csSqw_RemObject_Dll;
using csSqw_Dll;
using System.Threading;
// Класс формы, содержащей контейнер компонентов.В области клиента
// этой формы отображаются компоненты
public class SqwModels: Form
{
private static int numCompnts= 0; // Номер компонента
public SqwComp cs; // Ссылка на компонент
private Random rand; // Случайное число
public Container components = null;
// Конструктор
public SqwModels( )
{
components= new Container ( );
Text= "Контейнер и компоненты";
rand= new Random ( );
}
// Обработать событие от объекта класса RemObj
public void RemObjHandler (RemObjEventArgs args, ref ArrayList aL)
{
switch (args.command)
{
case "CreateAdd": CreateAdd ( );
break;
case "Remove": Remove (args.number );
break;
case "GetList": aL=GetList ( );
break;
}
}
// Создать компонент и добавить его в контейнер
public virtual void CreateAdd ( )
{
numCompnts++;
Point point= new Point ( );
point.X= rand.Next (this.ClientSize.Width);
point.Y= rand.Next (this.ClientSize.Height);
SqwComp cmpnt= new SqwComp
(numCompnts, point);
components.Add (cmpnt);
Invalidate ( );
}
// Удалить компонент с указанным номером
public virtual void Remove (int Num)
{
IEnumerator inum= components.Components.GetEnumerator ( );
while (inum.MoveNext( )) // Перебрать коллекцию
{
SqwComp cm= (SqwComp) inum.Current;
if (cm.Number == Num)
{
components.Remove (cm); // Удалить из контейнера
Invalidate ( );
break;
}
}
}
public virtual ArrayList GetList ()
{
ArrayList aL= new ArrayList ( ); // Создать объект списка
IEnumerator inum= components.Components.GetEnumerator ( );
while (inum.MoveNext ( )) // Перебрать компоненты
{ // контейнера
SqwComp cm= (SqwComp) inum.Current;
aL.Add (cm.Number); // Добавить номер в список
}
return aL; // Возвратить список
}
// Перерисовать область клиента прикладного окна сервера
protected override void OnPaint (PaintEventArgs e)
{
base.OnPaint (e);
// Нарисовать все компоненты из коллекции контейнера
IEnumerator inum=components.Components.GetEnumerator( );
while (inum.MoveNext ( )) // Перебрать коллекцию
{
SqwComp cm= (SqwComp) inum.Current;
e.Graphics.DrawRectangle(new Pen(Color.Blue, 5),
cm.Point.X-20, cm.Point.Y-20, 40, 40);
e.Graphics.DrawString (cm.Number.ToString ( ),
new Font("Arial", 9),
new SolidBrush (Color.Red), cm.Point.X, cm.Point.Y);
}
}
// Главная функция сервера
static void Main ( )
{
SqwModels sqwModels= new SqwModels ( );
sqwModels.Show ( );
RemObj remObj= new RemObj ( );
remObj.evToCont += new
FromRemObjToCont (sqwModels.RemObjHandler);
HttpChannel httpChannel;
try
{
httpChannel= new HttpChannel (8080);
ChannelServices.RegisterChannel (httpChannel);
}
catch(Exception e)
{
Console.WriteLine (e.Message);
return;
}
RemotingServices.Marshal(remObj, "RemoteObject");
Application.Run (sqwModels);
GC.Collect ( );
GC.WaitForPendingFinalizers ( );
}
}
/////////////////////////
// C# File csSqw_Client Клиент
// Подсоединить (Project/AddReference) csSqw_RemObj_Dll.dll
// Подсоединить (Project/AddReference) System.Runtime.Remoting.dll
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using csSqw_RemObject_Dll;
namespace csSqw_Client
{
// Класс основной формы с управляющими элементами
public class SqwMain: Form
{
private IRemObj iRemObj; // Ссылка на прокси
private Button butAdd; // Ссылка на кнопку добавления
private Button butDel; // Ссылка на кнопку удаления
private ListBox listBox; // Ссылка на элемент списка
int numComp= 0; // Номер очередного компонента
// Конструктор
public SqwMain ( )
{
Text= "Управление контейнером";
butAdd= new Button ( );
butAdd.Text= "Добавить компонент";
butAdd.Location= new Point (10,10);
butAdd.Size= new Size( 130,20);
butAdd.Click+= new EventHandler (ClickButAdd);
this.Controls.Add (butAdd);
//-----
butDel=new Button ( );
butDel.Text= “Удалить компонент с номером :";
butDel.Location= new Point (10,30);
butDel.Size= new Size (180, 20);
butDel.Click += new EventHandler (ClickButDel);
this.Controls.Add (butDel);
listBox= new ListBox ( );
listBox.Location= new Point (200, 30);
listBox.Size= new Size (60, 20);
this.Controls.Add (listBox);
/////////////////////////////////////////////
HttpChannel httpChannel= new HttpChannel (0);
ChannelServices.RegisterChannel (httpChannel);
iRemObj= (IRemObj) Activator.GetObject(
typeof (IRemObj),
"http://localhost:8080/RemoteObject");
}
// Обработчик кнопки "Добавить компонент"
void ClickButAdd (object o, EventArgs e)
{
numComp++;
iRemObj.CreateAdd ( ); // Создать и добавить компонент
// Обновить управляющий элемент списка
ArrayList aL=null;
listBox.Items.Clear ( );
aL= iRemObj.GetList ( ); // Возвратить список номеров
IEnumerator inum=aL.GetEnumerator();
while(inum.MoveNext ( ))
{
int num= (int)(Object) inum.Current;
listBox.Items.Add (num); // В управляющий элемент
}
Console.WriteLine ( );
}
// Обработчик кнопки “Удалить компонент с номером :"
void ClickButDel (object o, EventArgs e)
{
if (listBox.SelectedIndex==-1)
{
MessageBox.Show ("Выберете номер удаляемого
компонента");
}
else
{
int numSel= (int) listBox.SelectedItem;
listBox.Items.Remove (numSel);
iRemObj.Remove (numSel); // Удалить компонент
// Обновить управляющий элемент списка
ArrayList aL=null;
listBox.Items.Clear ( );
iRemObj.GetRef (ref aL);// Получить список номеров
for (int i= 0; i < aL.Count; i++)
{
int num= (int) aL[i];
listBox.Items.Add (num); // В упр-ий элемент
}
}
}
// Главная функция клиента
static void Main ( )
{
SqwMain sqwMain= new SqwMain ( );
Application.Run(sqwMain);
}
}
}