[개요]
이전 두개의 아티클에서 호스트 방식을 달리한(사용자정의호스트,IIS) 리모팅서비스 구축을
알아 보았다.
우리는 MarshalByRefObject 상속받는 리모트 클래스를 정의하고 그 클래스의 인스턴스를
원격지 클라이언트에서 사용하는 방법을 알고 있다.
앞서 살펴본 예제에서 우리가 정의한 리모트객체는 과연 어디에서 인스터스화 되었을까?
보통 클래스를 정의하고 그 클래스의 인스턴스를 생성(new 연산자를 통한)하면
실행 컴퓨터의 특정 메모리영역에 인스턴스가 올라가게 되고 그 메모리 주소가 참조를 잃기 전까지는
계속해서 그 인스턴스를 사용할 수 있는게 일반적이다.
또한 일정시간 이상 참조를 당하지 않는 객체는 가비지콜렉트로 넘겨져 GC에 의해 불특정한 시점에
메모리에서 사라지게 된다
그러면 리모팅 환경에서는 과연 어디(서버or클라이언트)의 메모리에 실제 클래스에 대한
인스턴스가 생성되며 그 객체의 수명은 어떻게 될까?
우선, 우리는 리모트객체의 두 가지 타입에대해 알아볼 필요가 있다.
물론 임대기반수명이라는 메커니즘도 존재하지만 이번 아티클에서는
리모트 객체의 타입에 따른 리모트객체의 생명주기와 개별 클라이언트에서의 상태공유를 알아 볼 것이다.
리모트객체의 종류
리모드 객체는 크게 두가지의 종류로 나누어 진다.
Ⅰ. 서버활성화 개체(Well-Known 개체) - 서버가 활성화 한 개체
①SingleCall 모드
②Signleton 모드
Ⅱ. 클라이언트활성화 개체 - 클라이언트가 활성화 한 개체
우선, 간략히 정리하자면 서버활성화 개체는 클라이언트에서 리모트 객체의 메서드를 호출할때 활성화 되며
클라이언트 활성화 개체는 클라이언트에서 new 연산자로 리모트 객체를 생성할때 활성화 된다.
주의할 것인 위의 서버/클라이언트 활성화 라는 말은 서버/클라리이언트 메모리에 인스턴스가 생긴다는 기준이 아니라
서버/클라이언트에서 리모팅 객체를 활성화 한다는 말이다.
그럼 이제 차례대로 그 차이점을 알아보도록 하자
1. Well-Known(SingleCall) 개체에 대해서 알아보자.
설정 파일의
<service>
<wellknown
mode="SingleCall"
type="RemotingServiceDemo.RemotingObject , RemotingObject"
objectUri="RemotingObject" />
</service>
이 부분에서 우리는 이미 개체의 종류를 명시하였다.
-SingleCall 모드에서는 두가지를 기억 하여야 한다.
㉠ 클라이언트에서 리모트객체의 메서드를 호출할 때 마다 새로운 객체가 만들어 진다.
㉡ (데이터의)상태유지가 되지 않는다.
- 예제를 통해 알아보자
* RemotingObject.cs (리모트 객체)
- 객체 생성 시점 확인을 위한 생성자와 데이터의 상태유지 확인을 위한 shareValue 라는 변수를 두었다.
using System;
namespace RemotingServiceDemo{
public class RemotingObject : System.MarshalByRefObject {
private int shareValue = 0;
public RemotingObject(){
Console.WriteLine("원격객체가 새로 생성되었습니다.");
}
public int ADD(){
return this.shareValue++;
}
}
}
* 서버 설정파일의 service 항목 - mode 를 SingleCall로..
<service>
<wellknown
mode="SingleCall"
type="RemotingServiceDemo.RemotingObject , RemotingObject"
objectUri="RemotingObject" />
</service>
* 클라이언트 실행 파일
- 리모트객체 생성시점과 데이터 공유 유/무를 확인하기 위해 메서드를 세번 호출한다.
using System;
using System.Runtime.Remoting;
using RemotingServiceDemo;
class SimpleClient{
public static void Main(){
RemotingConfiguration.Configure("Client.exe.config");
RemotingObject remoteObject = new RemotingObject();
for(int i=0; i < 3; i++)
Console.WriteLine(remoteObject.ADD().ToString());
}
}
* 클라이언트 설정 파일은 이전과 동일하다.
* 실행 결과

* 결론
실행화면을 보면 클라이언트에서 리모트 객체의 메서드를 호출할때마다
서버측 리모트객체의 생성자가 실행되며,
각각이 별도의 객체이므로 데이터의 공유는 전혀 되고 있지 않음을 알 수 있다.
이처럼 Well-Known 개체의 SingleCall 모드로 리모트 객체를 생성하면 데이터의 공유는 기대할수 없다.
2. Well-Known(Singleton) 개체에 대해서 알아보자.
설정 파일의 mode 부분만 바꿔주자
<wellknown
mode="Singleton"
type="RemotingServiceDemo.RemotingObject , RemotingObject"
objectUri="RemotingObject" />
* 클라이언트 실행파일
- 클라이언트에 new 연산자를 두번 사용해서 새로운 객체를 만드는것처럼 했다
using System;
using System.Runtime.Remoting;
using RemotingServiceDemo;
class SimpleClient{
public static void Main(){
RemotingConfiguration.Configure("Client.exe.config");
RemotingObject remoteObject = new RemotingObject();
for(int i=0; i < 3; i++)
Console.WriteLine(remoteObject.ADD().ToString());
RemotingObject remoteObject2 = new RemotingObject();
for(int i=0; i < 3; i++)
Console.WriteLine(remoteObject2.ADD().ToString());
}
}
-Singleton 모드에서도 두가지를 기억 하여야 한다.
㉠ 리모트개체는 클라이언트의 첫번째 메서드 호출시 리모트 객체가 단 한번 만들어 진다
다음번 메서드 호출부터는 같은 객체를 쓴다
㉡ (데이터의)상태유지가 가능하다.
* 실행 결과

* 결론
실행화면을 보면 리모트 객체는 클라이언트가 첫번째 메서드 호출시 단한번 생성되고
그 이후로는 이미 생성된 객체를 사용함을 알 수 있다.
하물며 RemotingObject remoteObject2 = new RemotingObject()
이 부분에서 클라이언트가 new 연산자로 새로운 리모트 객체를 생성하는 것처럼해도
같은 객체가 사용된다.
이것은 Well-Known 개체는 클라이언트의 new 연산자가 아닌 메서드 호출시
실제로 생성됨을 확연히 알 수 있는 대목이다.
결론적으로 Well-Known 의 Singleton 모드의 리모트 개체는 클라이언트의 첫번째 메서드 호출시
단 한번 생성되고,
GC에 넘어가기 각 클라이언트에서는 하나의 인스턴스를 사용하는 결과를 초래한다.
이것은 또한 각각의 클라이언트에서 데이타의 공유가 가능함을 의미하기도 한다.
3. 클라이언트 활성화 개체에 대해서 알아보자.
- 이 개체는 우리가 일반적으로 프로그램을 짤때 클래스의 인스턴스를 생성하는 개념과 유사하다.
즉 new 연산자를 통해서 인스턴스가 생성되고 각각의 new연산자로 생성된 인스턴스는
서로 다른 메모리 주소를 가지는 즉 서로다른 인스턴스가 되는 것이다.
-Singleton 모드에서는 두가지를 기억 하여야 한다.
㉠ 클라이언트에서 리모트객체를 new 연산자로 생성할때 서버에서 객체가 생성된다.
㉡ (데이터의)상태유지 가능하다. 단, Signton과는 달리 new 연산자로 생성된 각각의 객체내에서만.
- 예제를 통해 알아보자
* 서버 설정파일의 service 항목 - wellknown 를 activated 로..(종단점이 필요치 않다)
<service>
<activated
type="RemotingServiceDemo.RemotingObject , RemotingObject"
/>
</service>
* 클라이언트 설정파일 - 역시 wellknown 를 activated 로..(역시 종단점이 필요치 한다)
<client url="tcp://localhost:4989/ServerHosting">
<activated
type="RemotingServiceDemo.RemotingObject, RemotingObject"
url="tcp://localhost:4989/ServerHosting" />
</client>
* 실행 결과

* 결론
실행화면을 보면 리모트개체는 클라이언트에서 new 연산자로 리모트개체를 생성할때
실제로 생성됨을 알 수 있다
두번의 new 연산자로 두개의 리모트 객체를 생성한 셈이다.
여기서의 데이터 공유는 각 객체별로 공유가 가능하다.(일반적인 우리의 객체상식이다)
추가사항
리모트개체에 기본생성자 이외의 생성자 사용에 대해...
만일 리모트개체에 파라메타가 있는 생성자를 정의 했다고 하자.
그럼 클라이언트에서는 그 생성자를 호출 하기 위해서는 new 연산자로 파라메타를 넘겨줘야 한다.
그럼 Well-Known 과 클라이언트 활성화 개체 모두 기본생성자 이외의 생성자 사용이 가능할까??
이미 눈치를 채신분도 있으리라 본다.
답은 클라이언트 활성화 개체만 가능하다
상식적으로 생각해보자.
Well-Known 개체의 생성시점은 클라이언트의 new 연산자가 아닌 메서드 호출시 실제 리모트객체가 생성된다고 했다.
즉 파라메타가 있는 생성자에게 파라메타를 넘겨줄 방법이 없는 것이다.
그러나 클라이언트활성화타입의 개체사용시에는 new연산자로 넘겨주면 된느 것이고... (당연하죠? ^^;>
정리
이상 닷넷 리모팅서비스에서 리모트개체에 대한 타입과 그 타입에 따른 리모트개체 생성시점과
데이터 공유에 대해 알아 보았습니다.
감사합니다.
아래에는 간단히 비교한 표입니다.
|
Well-Known |
클라이언트 활성화 | ||
|
SingleCall |
Singleton |
||
|
객체 생성시점 |
클라이언트이 |
클라이언트의 첫번째 메서드 호출시 단한번. (new 로 생성되지는 않음) |
클라이언트의 new연산자 를 통한 리모트객체 생성시 마다. |
|
데이터 상태유지 |
X |
O |
O |
|
기본생성자 이외의 |
X |
X |
O |
- Microsoft Application Blocks for .NET (0)2007/01/11
- 가비지 수집기 기본 및 성능 힌트 (0)2007/01/11
- 닷넷 리모팅 서비스에 대한 이해3 - 리모트객체의... (0)2007/01/10
- 닷넷 리모팅 서비스에 대한 이해2 (iis를 호스트로... (0)2007/01/10
- 닷넷 리모팅 서비스에 대한 이해 (0)2007/01/10

수안이의 컴퓨터 연구실


Leave your greetings.