C# - Interfész távol implementált függvényének hívása

forráskód letöltése
A .NET Remoting szolgáltatásának köszönhetően egy tetszőleges szoftvercsatorna felhasználásával kapcsolatot teremthetünk alkalmazásaink között. Cikkünkben egy olyan távoli objektumot érünk el kliens-alkalmazásunk segítségével, mely valójában egy interfész, meghívandó metódusa – mellyel adatokat kaphat kliens-alkalmazásunk -, a szerver-alkalmazásban van implementálva.
A program használatakor ügyelnie kell arra, hogy az alkalmazások helyes sorrendben legyenek elindítva. Elsőként a RemoteServer alkalmazást kell elindítani.
A mellékelt példa RemotingInterface mappájában három projekt állományait találjuk, melyek megvalósítják a klienst, a szervert és a távoli objektumot.
Ahogy a bevezetőben említettük, a távoli objektumunk egy szabályos .NET interfész, melynek egyetlen GetData metódusát a szerver alkalmazás osztályában implementáltuk, meghívásra viszont a kliens-alkalmazásban történik. A GetData metódus úgy működik, hogy a szerver-alkalmazás mappájában mellékelve megtalálható products.xml állományban található adatokat egy logikai adattároló objektumba, egy DataSet objektumba tölti, és az adatokat tartalmazó DataTable objektumot visszatérési értékként visszaadja.
A .NET Framework Remoting szolgáltatásának, osztályainak eléréséhez meg kell adnunk referenciaként a System.Runtime.Remoting névteret. Ehhez válasszuk a Project - Add reference menüpontot, majd a megjelenő ablakban a .NET lapon keressük elő a System.Runtime.Remoting elemet. A forráskódot tartalmazó állományok elején meg kell adnunk, hogy a névtér osztályai közül melyekre van szükségünk.
RemoteLibrary projekt
A projektben tehát megvalósítjuk az interfészt, melynek tulajdonságait örökítjük a szerver objektum létrehozásakor.
public interface IRemoteInterface
{
  DataTable GetData();
}
Az IRemoteInterface interfész eléréséhez referenciaként mind a kliens-, mind a szerver-alkalmazásokhoz hozzá kell adnunk a RemoteLibrary elemet. Ehhez válasszuk a Project - Add reference menüpontot, majd a megjelenő ablakban a Projects lapon jelöljük ki az RemoteLibrary elemet.
RemoteServer projekt
A szerver-alkalmazás kódját tartalmazó állományok gyűjteménye, ahol a Form1.cs állomány fejlécében meg kell adnunk azokat a névtereket, melyeket használni kívánunk. Ezek között van az imént létrehozott interfész objektum névtere is:
using RemoteLibrary;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels ;
using System.Runtime.Remoting.Channels.Tcp;
Az interfész metódusának implementálásához létrehozunk egy RServer osztályt:
public class RServer : MarshalByRefObject , IRemoteInterface
{
  private DataSet ds = new DataSet();
  public RServer()
  { }
Látható, hogy az osztály részben az IRemoteInterface interfész tulajdonságait örökli. Az osztályban megalkotjuk a GetData metódus kódját:
  public DataTable GetData()
  {
    ds.ReadXml(Application.StartupPath + "\\products.xml");
    return ds.Tables[0];
  }
}
Init nevű saját metódusunkban megvalósítjuk a szoftvercsatorna lefoglalásához kapcsolódó tevékenységeket. Ez a szerver indításakor azonnal lefut. Először létrehozunk egy TCP csatornát:
private void Init()
{
  TcpServerChannel tsc = new TcpServerChannel(9999);
A csatornát regisztráljuk:
  ChannelServices.RegisterChannel(tsc);
Végül konfiguráljuk a szolgáltatást:
  RemotingConfiguration.RegisterWellKnownServiceType(typeof(RServer) , "RServer" , WellKnownObjectMode.Singleton);
  ...
}
A szervert elindítjuk, mely a 9999-es számú porton figyel, és várja a kliens kérését.
RemoteClient projekt
A kliens-alkalmazásban meghívjuk a szerver osztályában implementált GetData metódust, mely már egy feltöltött DataTable objektumot ad vissza. Az ebben található adatokat jelenítjük meg a DataGrid kontrolban.
A kliens kódját tartalmazó Form1.cs állomány fejlécében is meg kell adnunk a használni kívánt névtereket:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using RemoteLibrary;
Deklarálnunk kell egy interfész objektumot a metódus eléréséhez:
IRemoteInterface rInterface;
A program indulásakor lefutó Init metódusban valósítjuk meg a kapcsolatfelvételt. Kezdve a csatorna létrehozásával, és regisztrációjával:
private void Init()
{
  ChannelServices.RegisterChannel( new TcpClientChannel());
Megalkotjuk az interfész példányt:
  rInterface = (IRemoteInterface)Activator.GetObject(typeof(IRemoteInterface) , "tcp://localhost:9999/RServer");
  ...
}
Ha nem történik hiba a kapcsolatfelvételkor, vagyis a szerver-alkalmazás már elindult, akkor a használhatóvá váló, ADATBEOLVASÁS feliratú gombra kattintva egy DataTable objektum feltölthető adatokkal, és adatforrásul adható a DataGrid kontrolnak.
DataSet ds = new DataSet();
ds.Tables.Add(rInterface.GetData());
grid.DataSource = ds.Tables[0].DefaultView;