posted by 써니루루 2007. 3. 29. 15:45

먼저 리모팅(Remoting)을 이용하기 위해
1. 원격 객체를 작성한다.
2. 원격 객체를 Remoting 서비스할 Tcp, Http 채널을 각각 열어주는 서버를 제작한다.
3. 원격 객체를 다루게 될 Client를 Tcp, Http로 각각 작성한다.

위와 같은 순서로 프로젝트 4개를 작성하고 서로 원격 객체를 참조하고 리모팅 어셈블리를 참조해서 구현하게 됩니다.

TCP, HTTP 각각 체널에서 원격 프록시 객체(Remoting Proxy)를 생성하는 방법은 SAO 방법중 Activator.GetObject()를 사용하였다.

위의 예제 코드는 첨부 파일에 포함되어있습니다.

posted by 써니루루 2007. 3. 29. 11:47

활성화와 프록시 객체의 개요

  • 원격 객체 활성화 방법
    • 서버 활성화 객체(SAO: Server Activated Object) - Well Known 객체라고도 함
      • SingleCall 방식
        • 함수 호출 요청이 있을 때마다 객체 생성
      • Singleton 방식
        • 클라이언트 함수 호출 요청이 있을 때 단 하나의 객체를 생성한 후 하나의 객체를 공유
    • 클라이언트 활성화 객체(CAO: Client Activated Object)
  • 서버 활성화와 클라이언트 활성화
    • 서버에 의해서 원격 객체가 자동으로 만들어지면 서버 활성화 기법이라고 한다.
    • 클라이언트에서 프록시 객체를 만들 때 원격 객체가 만들어지면 클라이언트 활성화 기법이라고 한다.
  • 클라이언트의 프록시
    • 클라이언트에서는 원격 객체를 참조하기 위한 가상의 객체를 만들게 되는데 이 객체를 프록시 객체라고 한다.
    • 이 프록시 객체를 이용해서 클라이언트는 원격 객체를 핸들할 수 있다.
  • 프록시 객체를 생성하는 방법
    • new를 사용하는 방법 : 서버 활성화, 클라이언트 활성화에서 사용
    • Activator.GetObject() 함수를 사용하는 방법 : 서버 활성화에서 사용
    • Activator.CreateInstance () 함수를 사용하는 방법 : 클라이언트 활성화에서 사용


클라이언트 활성화 객체로 프록시 객체 생성
클라이언트 활성화 객체 방식으로 프록시 객체를 생성하는 방법에는 new와 Activator.CreateInstance() 두가지 방법을 사용할 수 있다.

다음은 그 예를 보여준다.

// 1. new 키워드로 생성
RemotingConfiguration.RegisterActivatedClientType(
typeof(CaoHello.CaoHello)
, "tcp://localhost:9009/"
);

CaoHello.CaoHello h = new CaoHello.CaoHello(pars[0].ToString());

// 2. CreateInstance로 클라이언트 생성
object obj = Activator.CreateInstance(typeof(CaoHello.CaoHello), pars, attrs);
CaoHello.CaoHello h = (CaoHello.CaoHello)obj;



서버 활성화 객체로 프록시 객체 생성
- new를 사용하는 방법 : 서버 활성화
- Activator.GetObject() 함수를 사용하는 방법
- RemotingService.Connect()를 이용한 프록시 생성
            // 1. Activator.GetObject() 를 이용한 SAO
            object obj = Activator.GetObject(
                typeof(SaoHello.SaoHello)
                , "tcp://localhost:9099/BaboSaoHello"
            );
            SaoHello.SaoHello h = (SaoHello.SaoHello)obj;

            // 2. New를 이용한 SAO
            WellKnownClientTypeEntry entry = new WellKnownClientTypeEntry(
                typeof(SaoHello.SaoHello)
                , "tcp://localhost:9099/BaboSaoHello"
            );
            RemotingConfiguration.RegisterWellKnownClientType(entry);
            SaoHello.SaoHello h = new SaoHello.SaoHello();

            // 3. RemotingServices.Connect()를 이용한 SAO
            object obj = RemotingServices.Connect(
                typeof(SaoHello.SaoHello)
                , "tcp://localhost:9099/BaboSaoHello"
            );
            SaoHello.SaoHello h = (SaoHello.SaoHello)obj;
posted by 써니루루 2007. 3. 28. 16:34
기존 리모팅 예제코드를 보셨다면 추가적으로 다음 예제를 해보면 도움이 될 것이다.
http://net2.tistory.com/entry/XFile-4


1. 리모팅을 이용하여 계산을 처리하는 Calc.dll을 윈도우즈 Service에 등록시키고,
서비스를 시작시킨 상태에서 윈 폼으로 리모팅을 호출하여 계산값을 얻어낸다.

(계산을 간단히 코드상에서 처리할 수 있지만 예제로 리모팅을 사용하는 방법을 배워보도록 하자.)

invalid-file

리모팅, 윈도우즈 서비스, 계산기



2. 리모팅을 이용하여 Database에 ADO.NET으로 연결해 쿼리 데이터를 DataSet으로 반환하는 *.dll 을 작성한다. 이 dll을 윈도우즈 서비스에 등록시키고 시작시킨 상태에서 윈폼에 DataGridView 컨트롤에 리모팅으로 받아온 DataSet을 뿌려주는 예제이다.
예제코드의 쿼리문과 Database 연결 코드는 직접 수정해야 할 것이다.

invalid-file

리모팅, 윈도우즈 서비스, DataSet

posted by 써니루루 2007. 3. 28. 12:53

.NET Remoting이란?

  • RPC(Remote Procedure Call)

    • 클라이언트가 원격지에 존재하는 함수를 호출한 후, 그 결과를 원격지로부터 받아내는 기술
  • 리모팅(Remotion)
    • 리모팅은 서비스 개념을 포함한다
    • 원격 서버가 클라이언트에게 서비스(Service)를 제공한다.
  • 닷넷 리모팅에서 소개되는 기술
    • 원격 객체(Remote Object)
    • 원격 객체를 대신하는 클라이언트 프록시 객체(Proxy Object)
    • 마샬링(Marshaling), 언마샬링(Unmarshaling)
    • 직렬화(Serialization), 역직렬화(Deserialization)
    • 네트워크 통신을 위한 체널(Channel)
    • 네트워크로 전송되는 데이터를 인코딩하는 포멧터(Formatter)

.NET Remoting의 구성요소

  • 서버원격 시스템의 구성
    • 원격 클래스와 원격 객체
    • 채널(Channel)
    • 포멧터(Formatter)
      • 데이터를 해석하기 편리하고 전송하기 좋은 형식으로 인코딩 또는 디코딩해야 하는데 이 역할을 담당하는 것이 포멧터이다.
  • .NET Remoting에서 제공해주는 포멧터
    • 포멧터(SoapFormatter)
      • 데이터를 XML 형식의 SOAP 방식으로 인코딩
    • Binary 포멧터(BinaryFormatter)
      • 말그대로 Binary 형식으로 인코딩하기 때문에 인코딩 속도면에서 효율적이지만, 이기종간의 통신 포멧인 SOAP을 이용하는 것이 좋다.
  • 클라이언트 원격 시스템의 구성 요소
    • 프록시 객체(Proxy Object)
      • 원격 시스템에서 클라이언트와 서버 사이를 넘나드는 참조값
    • 채널(Channel)
      • 클라이언트와 원격 서버와 통신하기 위해 존재
    • 포멧터(Formatter)
  • .NET Remoting에서 지원하는 채널의 종류
    • HTTP 채널(HttpChannel)
    • TCP 채널(TcpChannel)
원격 시스템의 구조

원격 시스템의 구조 다이어그램




.NET Remoting의 가장 간단한 예(서버)

  • 원격 서버 프로그램 작성 과정
    • 원격 클래스 작성
    • 원격 서버 프로그램 작성
    • 클라이언트 프로그램 작성
  • 원격 클래스 작성
    • 일단 클래스와 동일하지만 MarshalByRefObject 를 상속받는 것만 다르다

예제 : 원격 클래스 Server/Hello.cs

/**

서비스할 원격 클래스

**/

using System;

public class Hello : MarshalByRefObject

{

public Hello()

{

Console.WriteLine("Hello 생성자 호출");

}

public String SayHello(String name)

{

Console.WriteLine("Hello의 SayHello() 메서드 호출, 매개변수:{0}", name);

return "안녕하세요! [" + name + "] 님";

}

~Hello()

{

Console.WriteLine("Hello 소멸자 호출");

}

}

/***

c:csharpchap14ex01Server> csc /target:library /out:Hello.dll Hello.cs

***/



예제 : 리모트 서버 /Server/HelloServer.cs

/**

원격 클래스를 서비스하는 간단한 서버 프로그램

**/

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

public class HelloServer

{

public static void Main()

{

TcpChannel channel = new TcpChannel(9009);

ChannelServices.RegisterChannel(channel, false);

RemotingConfiguration.RegisterWellKnownServiceType(

Type.GetType("Hello, Hello"),

"BaboHello",

WellKnownObjectMode.SingleCall);

System.Console.WriteLine("서버를 멈추려면 Enter를 누르세요!");

System.Console.ReadLine();

}

}

/***

c:csharpchap14ex01Server> csc /r:Hello.dll HelloServer.cs

c:csharpchap14ex01Server> HelloServer

서버를 멈추려면 Enter를 누르세요!

[참고] .NET Framework 1.0과 1.1에서는 ChannelServices.RegisterChannel(channel)과 같은 방식으로 사용하였다. 하지만 채널만을 입력받는 이 함수는 2.0에서 Obsolete되었다.

이 함수대신 ChannelServices.RegisterChannel(channel, false)와 같이 사용해야 한다. 첫번째 매개변수는 이전과 같이 채널이며 두번째 매개변수는 보안설정이 있는지 없는지를 나타낸다.

***/





예: 원격 클라이언트 Client/HelloClient.cs

/**

원격 서비스를 이용하는 간단한 클라이언트 프로그램

**/

using System;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

public class HelloClient

{

public static int Main(string[] args)

{

TcpChannel channel = new TcpChannel();

ChannelServices.RegisterChannel(channel, false);

object obj = Activator.GetObject(typeof(Hello),

"tcp://localhost:9009/BaboHello");

Hello h = (Hello)obj;

Console.WriteLine(h.SayHello("홍길동"));

return 0;

}

}

/***

1. 원격 클라이언트 실행

c:csharpchap14ex01Client> csc /r:Hello.dll HelloClient.cs

c:csharpchap14ex01Client> HelloClient

안녕하세요! [홍길동] 님

c:csharpchap14ex01Client> HelloClient

안녕하세요! [홍길동] 님

2. 원격 서버 프로그램 (클라이언트 접속후)

c:csharpchap14ex01Server> HelloServer

서버를 멈추려면 Enter를 누르세요!

Hello 생성자 호출

Hello의 SayHello() 메서드 호출, 매개변수:홍길동

Hello 생성자 호출

Hello의 SayHello() 메서드 호출, 매개변수:홍길동

3. 원격 서버 프로그램이 종료했을 때

c:csharpchap14ex01Server> HelloServer

서버를 멈추려면 Enter를 누르세요!

Hello 생성자 호출

Hello의 SayHello() 메서드 호출, 매개변수:홍길동

Hello 생성자 호출

Hello의 SayHello() 메서드 호출, 매개변수:홍길동

Hello 소멸자 호출

Hello 소멸자 호출

[참고]

클라이언트 프로그램을 컴파일하고 실행하기 위해서는 서버의 Hello.dll이 필요하다. 여기서는 여러분이 수동으로 클라이언트의 디렉토리에 복사해주어야 한다.

***/




예제를 사용하는 법 :

1. Hello 원격 클래스를 먼저 컴파일해서 dll 파일로 만든다.
2. 리모트 서비스를 작성해서 띄워놓는다.
3. 리모트 클라이언트를 띄워서 리모트 서비스측에 원격 객체가 생성되는지 확인한다.