이벤트 계층 개발

ProObject 런타임은 이벤트 드리븐으로 방식으로 동작하며, 이벤트는 채널 이벤트이벤트 두 종류로 구분되어 사용된다. 본 장에서는 이벤트 계층과 이벤트 계층에서 사용되는 리소스인 이벤트와 이벤트 핸들러를 개발하는 방법에 대하여 설명한다.

1. 개요

이벤트 계층은 애플리케이션에 정의된 이벤트들을 정의하는 애플리케이션 이벤트를 처리한다.

채널 이벤트 계층에서는 정해진 채널 이벤트를 단순히 처리를 하는 것에 불과하였다면, 이벤트 계층에서는 애플리케이션만의 이벤트들을 정의하고 그 이벤트를 처리하는 이벤트 핸들러(Event Handler)를 별도로 둘 수 있다. 이벤트 계층에서 처리되는 이벤트는 채널 이벤트 계층이나 다른 이벤트 핸들러에서만 발생하는 것이 가능하다.

이때 발생되는 이벤트는 같은 애플리케이션에 속하는 채널 이벤트 핸들러나 이벤트 핸들러의 경우에서만 발생될 수 있으며, 오직 시스템 이벤트의 경우만 예외로 처리된다.

일반적으로 이벤트 영역에서 처리되는 이벤트는 다음과 같이 2가지로 구분된다.

  • 시스템 이벤트

    애플리케이션에 종속되지 않으며, 런타임 엔진에서 공통적으로 처리되는 이벤트이다. 시스템 이벤트 중에서 사용자가 사용할 수 있는 이벤트는 서비스 요청 이벤트와 타이머 이벤트이다. 이에 대한 내용은 서비스 연동타이머 이벤트 연동에서 확인할 수 있다.

  • 사용자 정의 이벤트

    개발자가 사용하기를 위해 직접 작성한 이벤트이다. 개발자는 사용자 정의 이벤트를 생성할 때 반드시 이벤트와 이벤트 핸들러 리소스를 작성하여야 하며 이에 대한 내용은 이벤트 리소스 개발에서 확인할 수 있다.

시스템 이벤트의 경우에는 다른 애플리케이션의 이벤트를 발생시킬 수 있도록 조치가 가능하지만, 사용자 정의 이벤트는 자신이 속한 애플리케이션의 이벤트만을 발생시킬 수 있다는 점을 유의하도록 한다.

이벤트 계층에서 처리되는 이벤트는 반드시 채널 이벤트 계층에서부터 시작되어야 하며, 채널 이벤트 계층으로부터 이벤트가 시작되지 않으면 그 어떠한 이벤트도 발생될 수 없다. 물론 이벤트 핸들러 내에서 다른 이벤트를 발생시키는 것은 가능하지만 최초 시작 이벤트가 발생되기 전에는 그 어떠한 이벤트 핸들러도 호출될 수 없기 때문에 모든 이벤트는 채널 이벤트로부터 시작된다.

다음은 채널 이벤트 계층과 이벤트 계층의 프로세스 수행에 대한 설명이다 .

figure event layer relation
채널 이벤트 계층과 이벤트 계층의 프로세스 수행

한 번 시작된 이벤트는 다른 이벤트를 발생시키고, 발생된 이벤트가 또 다른 이벤트를 발생할 수 있는 등 다수의 이벤트가 엮여 하나의 서비스를 처리하는 과정을 거치게 된다.

ProObject에서는 이러한 과정에서 여러 이벤트들이 사슬처럼 얽혀있다고 하여 이벤트 체인(Event-Chain)이라는 용어로 정의하여 사용하고 있으며, 채널 이벤트 핸들러는 이러한 이벤트 체인을 시작하는 역할을 주로 담당한다.

이벤트 계층에서 채널 이벤트 계층으로 채널 이벤트를 발생시키는 것을 이벤트 체인이 종료되었다고 인식하지 않는다. 이는 이벤트를 처리하는 도중 데이터베이스나 다른 서버로 서비스를 요청하거나 외부와의 통신을 하는 등의 채널 상호작용을 해야 하는 일이 자주 발생하기 때문이다.

채널 이벤트 영역에서는 외부와의 통신을 마친 후 이미 존재하는 '이벤트 체인에 새로운 이벤트를 발생시켜 엮어주는' 작업을 통해 새로운 이벤트를 발생시키는 것이 가능하다. 이때에는 이벤트를 새로 시작했다고 하지 않고, 기존에 채널 이벤트를 요청한 이벤트 핸들러의 작업을 재개한다는 개념으로 인식하기 때문에 채널 이벤트 핸들러에서는 resumeEvent 메소드를 활용하게 된다. 채널 이벤트에서 이벤트를 시작하고 재개하는 방법은 이벤트 연동에 설명되어 있으므로 참고한다.

2. 이벤트 리소스 개발

ProObject의 이벤트는 타입이 정의된 거대한 데이터 오브젝트(DataObject)의 한 종류이다. 이벤트는 이벤트의 속성과 발생한 이벤트에 대한 전체적인 정보를 담고 있는 하나의 거대한 구조체의 형태이다. 이벤트 핸들러는 이벤트가 발생했을 때 해당 이벤트의 정보가 담긴 이벤트 객체를 전달받아 작업을 수행한다.

필요한 경우에는 이벤트 체인에 할당된 사용자 정보(UserContext)나 세션(Session)를 이용하여 상태를 저장/유지하고 후에 이용할 수 있지만 일반적으로 이벤트를 처리할 때에는 반드시 전달된 이벤트 객체만을 이용해 작업을 처리할 것을 권고한다.

본 절에서는 이벤트 계층에서 사용되는 리소스인 이벤트와 이벤트 핸들러를 작성하는 방법에 대해서 설명한다.

개발된 리소스는 애플리케이션 내의 이벤트 디렉터리(${APP_HOME}/event/) 내에 배포된다.

2.1. 이벤트 개발

본 절에서는 이벤트 클래스를 작성하는 방법에 대하여 설명한다.

ProObject의 이벤트는 사건에 대한 전반적인 정보를 담고 있는 객체로 정의된다. 따라서 이벤트는 사건에 대한 정보들을 담을 수 있는 Getter/Setter 메소드를 포함해야 하며, 각 이벤트의 종류를 구분할 수 있도록 타입을 반드시 지정해야 한다. ProObject 런타임의 이벤트는 정수(int) 값을 통해 서로를 구분하게 되어 있으며, 이 타입 값은 절대로 중복되면 안된다.

2.1.1. 이벤트 클래스 작성

이벤트 클래스는 반드시 com.tmax.proobject.model.event.Event 추상 클래스를 상속받아 getType 메소드를 자신의 타입 값을 전달하도록 코드를 작성해주어야 한다. 해당 메소드는 런타임 엔진에 이벤트의 타입을 알기 위해 자동으로 호출한다.

다음의 메소드를 오버라이딩한다.

public int getType()

그 외의 특별한 제약 사항은 없으며 이벤트 객체는 단순 데이터 오브젝트의 개념으로 인식되는 만큼 대부분의 정보를 넣거나 얻을 수 있도록 메소드를 작성할 수 있다.

2.1.2. 이벤트 클래스 등록

이벤트 리소스의 작성 후 해당 클래스를 이벤트 환경설정 파일에 등록해야 한다. 이벤트 설정 파일에 대한 자세한 설명은 이벤트 등록을 참고한다.

2.2. 이벤트 핸들러 개발

이벤트 계층는 기본적으로 채널 이벤트 계층를 포함하지만 본 절에서는 채널 이벤트를 제외한 애플리케이션 이벤트를 다루는 이벤트 핸들러(Event Handler)만을 설명한다.

한 번 애플리케이션 이벤트가 발생하면 ProObject는 해당 이벤트를 처리하는 이벤트 핸들러에 이벤트 객체를 전달해 이벤트를 처리할 것을 요청한다.

이벤트 핸들러는 전달받은 이벤트 객체를 바탕으로 이벤트을 처리하게 되며, 이벤트를 처리한 이후에는 이벤트 처리가 완료되었음을 알려주는 이벤트를 새로 발생시키거나, 해당 이벤트 처리를 마지막으로 서비스의 처리를 종료하는 등의 모든 작업을 수행한다. 이 모든 작업은 모두 이벤트 핸들러 객체 내에서 처리할 수 있으며, ProObject에서는 기본적으로 이벤트가 발생할 때마다 새로운 이벤트 핸들러(Event Handler) 객체가 할당되어 이벤트를 처리하게 된다.

ProObject에서 이벤트 핸들러는 이벤트를 처리하는 객체(Object)로 바라보며, 이는 서비스 처리에 대한 로직을 서비스 오브젝트(ServiceObject)로 매핑한 것과 같다. 따라서 ProObject의 이벤트 핸들러의 개발은 곧 이벤트를 처리하는 객체를 개발하는 것과 동일하며, 이벤트를 하나 추가할 때마다 해당 이벤트를 처리할 이벤트 핸들러를 함께 개발해야 한다.

다음은 ProObject의 이벤트 핸들러를 개발해야 하는 경우 고려해야할 사항에 대한 설명이다.

  • 객체 기반 프로그래밍(Object-Oriented Programming)

    ProObject에서 이벤트를 처리하는 객체를 작성할 때 업무 애플리케이션(Business Application)을 통해서 영역을 나누어 개발하기 때문에 이벤트 드리븐(Event-Driven)으로 서비스를 직접 작성하지 않는 한 Node.js나 Reactive Programming처럼 데이터 흐름에 초점을 맞춘 형태로 코드를 작성할 수 없다.

    대신 개발자가 영역에 맞추어 개발을 진행할 수 있도록 프로그래밍 모델을 제공해서 의존성(Dependency)이 끊어진 하나의 로직을 처리하는 객체를 작성할 수 있다. 데이터 흐름에 초점을 맞추지 않기 때문에 일반적으로 사용하는 콜백(Callback) 함수/객체를 전달하는 방식은 허용하지 않는 대신 이벤트의 처리 결과를 콜백과 동일한 방식으로 처리 완료 이벤트를 받을 수 있는 방법을 제공한다.

  • 상태 보존 없음(Stateless)

    ProObject의 이벤트 핸들러 또한 서비스와 동일하게 기존의 값을 저장하여 사용하는 것을 허용하지 않는다. 때문에 계산의 중간값을 잘못 저장하였다가 새로운 서비스가 해당 값을 잘못 참조하여 업무가 오류가 발행하는 현상을 미연에 방지한다.

    다만 발생된 이벤트를 하나의 유일 객체를 이용해서 중앙에서 처리하도록 하는 이벤트 기반 제어 방식의 프로그래밍 모델 개발이 필요한 경우에 한해 상태 보존이 허락된다.

이때 이벤트 핸들러는 자신이 처리를 담당하는 이벤트를 처리하는 것 외에 자신이 처리한 이벤트의 처리 완료 이벤트를 발생시키는 것이 가능하다.

다음은 이벤트 핸들러의 동작방식에 대한 설명이다. EventHandler A는 Event A가 발생하는 경우 처리하고 EventHandler B는 Event B가 발생하면 처리한다.

figure event handler execution
이벤트 핸들러의 개괄적인 동작
  1. EventHandler A는 EventA가 발생하면 'handleEvent' 메소드에서 해당 이벤트를 처리하게 된다.

  2. EventHandler A가 Event A를 처리하다가 필요에 의해 Event B를 발생시키면 EventHandlerB에서 해당 EventB를 처리한다.

  3. EventHandler B는 Event B의 처리를 마무리한 후 Event B`을 발생시켜 Event B의 처리가 완료되었다는 이벤트를 발생시킨다. (처리 완료 이벤트)

  4. EventHandler B에서 처리 완료 이벤트가 발생하게 되면, Event B를 발생시켰던 EventHandler A가 Event B를 발생시킨 Event A 와 Event B`을 함께 handleResponseEvent 메소드로 전달받아 이후 이벤트를 처리하게 된다.

위 그림에서는 여기까지만 이벤트를 처리하도록 구현되어 있으나 handleResponseEvent 메소드에서 채널 이벤트를 발생시키거나 별도의 이벤트를 발생시키면 위와 유사한 방식으로 비슷하게 이벤트 처리의 흐름이 이어지게 된다.

2.2.1. 이벤트 핸들러 클래스 작성

이벤트 핸들러를 작성할 때에는 com.tmax.proobject.model.event.EventHandler 클래스를 상속받아 클래스를 작성해야 한다.

EventHandler 클래스를 상속받으면 이벤트 핸들러의 성격에 따라 Constructor 두 개 중 하나를 선택해서 구현한다.

  • Constructor 1)

    public EventHandler(int eventId)

    이벤트를 처리만 하고 처리 완료 이벤트를 발생시키지 않는 경우 사용된다. 채널 이벤트를 제외하고, 애플리케이션 이벤트를 발생시킨 곳에서 별도로 처리 완료 이벤트를 받을 필요가 없는 경우에 사용한다.

  • Constructor 2)

    public EventHandler(int eventId, int responseEventId)

    이벤트를 처리한 후 처리 완료 이벤트를 발생시키는 경우 사용한다. 서비스를 처리한 후 서비스의 응답 이벤트를 발생시키는 경우처럼 처리 완료 이벤트를 이벤트를 발생시킨 곳에서 받아 처리해야 하는 경우에 사용한다.

Constructor를 구현한 후에는 해당 이벤트 핸들러에 할당된 이벤트를 처리하기 위해 사용되는 추상 메소드인 handleEvent 메소드를 구현해야 한다. onEvent 메소드를 오버라이하면 대부분의 이벤트 처리가 가능하다.

public void onEvent(Event event, UserContext context) throws Throwable
매개변수 설명

event

발생한 이벤트의 객체가 전달된다.

context

이벤트 체인 내에서 공유되는 사용자 정보가 저장되는 저장소로, 이벤트 체인 내에서 공유하는 임시 변수들을 등록하여 사용할 수 있다.

다음은 로그를 작성하는 로그 작성 이벤트를 처리하는 이벤트 핸들러의 작성 예이다.

public class LogEventHandler extends EventHandler {
    public LogEventHandler(int eventType) {
        super(eventType);
    }

    @Override
    public void onEvent(Event event, UserContext context) throws Throwable {
        LogEvent log = (LogEvent)event;
        EventLogger().getLogger.log(log.getLogRecord());
    }
}

이벤트 핸들러 내에서 이벤트를 발생시키고 이벤트의 처리 결과를 받아 별도로 처리하려면 onResponseEvent 메소드를 오버라이딩해야 한다.

public boolean onResponseEvent(Event event, Event responseEvent, UserContext userContext) throws Throwable
매개변수 설명

event

해당 이벤트 핸들러에서 다른 이벤트를 발생시켰을 때 처리하고 있던 이벤트 객체가 전달된다.

responseEvent

발생시켰던 이벤트의 처리 완료 이벤트가 전달된다.

context

이벤트 체인 내에서 공유되는 사용자 정보가 저장되는 저장소로, 이벤트 체인 내에서 공유하는 임시 변수들을 등록하여 사용할 수 있다.

해당 메소드는 반환값은 boolean으로 이벤트 핸들러가 전달받은 처리 완료 이벤트를 성공적으로 처리하였는지에 대한 결과이다.

false가 반환되면 런타임 엔진은 처리 완료 이벤트가 성공적으로 처리되었다고 판단한다. true를 반환하는 경우 런타임 엔진은 해당 처리 완료 이벤트가 다른 곳으로도 전달되어야 한다고 인식하여, 처리 결과 이벤트를 발생시킨 이벤트 핸들러에 처리 완료 이벤트를 전달한다. 처리 완료 이벤트가 전달되다가 더 이상 전달되지 않거나, 특정 이벤트 핸들러에서 false를 반환하면 더 이상 처리 완료 이벤트를 전달하지 않는다.

다음은 onResponseEvent의 처리 결과를 전달하는 과정에 대한 설명이다.

figure event layer propagation
처리 완료 이벤트의 전달 과정

EventHandler B의 onResponseEvent 메소드에서 false를 반환하면 EventHandler의 처리 완료 이벤트가 EventHandler A에게로 전달된다. 이벤트 핸들러를 구현할 때에는 위의 구조를 이용하여 여러 이벤트의 Proxy 역할을 하는 특정 이벤트 핸들러를 작성할 수도 있으나 위의 과정을 잘못 처리하게 되면 이벤트 체인이 이상하게 점프(Jump)하는 현상이 나타나게 되므로 주의한다.

다음은 위의 처리 완료 이벤트의 전파를 제외하고 완료 이벤트의 응답을 받아 작업을 처리하는 이벤트 핸들러의 예제이다.

로그 이벤트 핸들러에서 별도로 로그를 데이터베이스에 기록하는 각각의 서비스를 호출한다고 가정한다. 이때 데이터베이스에 로그 기록을 실패한 경우에는 다시 서비스를 호출하고, 처리가 완료되면 실제로 로그를 남기는 방식으로 이벤트 핸들러를 구현한다.

public class LogEventHandler extends EventHandler {
    public LogEventHandler(int eventType) {
        super(eventType);
    }

    @Override
   /** (1) **/
    public void onEvent(Event event, UserContext context) throws Throwable {
        LogEvent log = (LogEvent)event;

        ServiceRequestEvent reqeust = new ServiceRequestEvent(
                     new ServiceName("test.example.DatabaseLogWrite", log.getLogRecord());
        EventManager.postEvent(request);
    }

    @Override
    /** (2) **/
    public boolean onResponseEvent(Event event, Event responseEvent, UserContext userContext) throws Throwable {
        switch(event.getType()) {
            Event.EVENT_SERVICE_RESPONSE :
                ServiceResponseEvent response = (ServiceResponseEvent)event;
                if(response.hasException()) {
                    ServiceRequestEvent reqeust = new ServiceRequestEvent(
                             new ServiceName("test.example.DatabaseLogWrite", log.getLogRecord());
                    EventManager.postEvent(request);
                } else {
                    LogEvent log = (LogEvent)event;
                    EventLogger().getLogger.log(log.getLogRecord());
                }
                break;
        }
        return false;
    }
}
  • (1) onEvent로 전달된 event와 onResponseEvent로 전달된 event는 같은 객체를 가르키게 된다. 이때 같은 이벤트 객체를 처리하는 이벤트 핸들러는 기본적으로 같은 객체로, 단일 객체(Singleton) 설정이 유지되지 않은 경우에도 이는 성립한다. 해당 설정에 대한 자세한 내용은 이벤트 핸들러 등록을 참고한다.

  • (2) onResponseEvent를 살펴보면 이벤트를 발생시키기 위해 EventManager를 이용하는 코드를 볼 수 있는데, 이에 대한 자세한 내용은 이벤트 연동을 참고한다. 위의 코드에서는 onResponseEvent에서 false 값을 반환하는 것을 볼 수 있는데, 이는 현재 전달된 처리 완료 이벤트를 성공적으로 처리하였으므로 처리 완료 이벤트를 전파하지 않겠다고 표기한 상태이다.

2.2.2. 이벤트 핸들러 등록

이벤트 핸들러 리소스를 작성하였다면 해당 클래스를 런타임에 등록하는 과정이 필요하다. 이벤트 설정 파일에 대한 자세한 설명은 이벤트 핸들러 등록을 참고한다.

3. 이벤트 리소스 등록

작성된 이벤트 리소스는 이벤트 환경설정 파일에 이벤트 리소스들을 등록하는 과정이 필요하다.

이벤트 리소스는 다음의 파일에 등록한다. 디렉터리 구조에 대한 자세한 설명은 애플리케이션 디렉터리 구조를 참고한다.

${APP_HOME}/config/event.xml

해당 파일이 없는 경우 파일을 생성하여 사용되고 기본 형태는 아래와 같다.

<event-meta>
    <!-- 이벤트 리소스 -->
</event-meta>

이벤트 리소스는 이벤트와 이벤트 핸들러로 구성되며, 각각 등록하는 방법은 이벤트 등록이벤트 핸들러 등록을 참고한다.

3.1. 이벤트 등록

이벤트를 등록하기 위해서는 이벤트 환경설정 파일에 이벤트를 등록해야 한다.

다음은 이벤트를 등록하는 예제이다.

<event-meta>
    <event>
        <id>100</id>
        <name>TestEvent</name>
        <class-name>com.proobject.test.TestEvent</class-name>
    </event>
</event-meta>

다음은 각 항목에 대한 설명이다.

태그 설명

<id>

이벤트의 타입을 지정한다. 256 ~ Integer.MAX_VALUE 사이의 값을 지정한다. 이벤트 클래스 내에서도 반드시 이 이벤트 타입과 동일한 값을 반환해야 한다.

<name>

이벤트의 이름을 지정한다.

<class-name>

작성한 이벤트 클래스의 이름을 패키지를 포함하여 지정한다.

3.2. 이벤트 핸들러 등록

이벤트 핸들러를 등록하기 위해서는 이벤트 환경설정 파일에 이벤트 핸들러를 등록해야 한다.

다음은 이벤트 핸들러를 등록하는 예제이다.

<event-meta>
   <event-handler>
       <name>TestEvent</name>
       <class-name>com.proobject.test.TestEvent</class-name>
       <singleton>false</singleton>
       <event-id>100</event-id>
       <respnose-event-id>101</response-event-id>
   </event-handler>
</event-meta>

다음은 각 항목에 대한 설명이다.

태그 설명

<name>

이벤트 핸들러의 이름을 지정한다.

<class-name>

작성한 이벤트 핸들러의 클래스의 이름을 패키지를 포함하여 지정한다.

<singleton>

이벤트 핸들러를 단일 인스턴스 상태로 이용할지 여부를 지정한다.

  • true : 이벤트가 발생될 때 마다 이벤트 객체가 새로 생성되지 않으며 기존의 이벤트 핸들러가 재활용된다.

  • false : 이벤트가 발생될 때 마다 이벤트 핸들러 객체가 새로 생성된다. (기본값)

<event-id>

이벤트 핸들러가 처리할 이벤트의 타입을 지정한다. 설정 값은 반드시 이벤트 등록을 통해 등록된 이벤트 타입이어야 한다.

<response-event-id>

이벤트 핸들러의 처리 완료 이벤트의 타입을 지정한다. 설정 값은 반드시 이벤트 등록을 통해 등록된 이벤트 타입이어야 한다.

본 절에서는 이벤트 핸들러 내에서 다른 이벤트나 처리 완료 이벤트를 발생시키는 방법과 채널 이벤트와 연동하는 방법에 대해 설명한다.

4.1. 채널 이벤트 연동

이벤트 핸들러에서 작업을 처리한 이후 다른 채널에 데이터를 쓰거나 서비스를 요청한 클라이언트에게 응답을 돌려줄 수 있다. 이 경우 ChannelEventManager를 이용하여 채널 이벤트와 연동을 하게 되며, 쓰기 이벤트만을 발생키시는 것이 가능하다. 채널 이벤트에 대한 자세한 설명은 채널 이벤트 계층 개발을 참고한다.

다음은 서비스를 최초로 요청했던 채널에 "OUTPUT" 문자열의 byte[]에 대해 쓰기 이벤트를 발생시키는 예제이다.

ChannelWriteEvent writeEvent = new ChannelWriteEvent(userContext.getRequestContext().getResponser().getChannelHandler(), "OUTPUT".getBytes());
ChannelEventManager.postChannelEvent(writeEvent, userContext);

위와 같이 ChannelWriteEvent 객체를 생성하며, 이때 원하는 채널 이벤트 핸들러 객체와 쓰기를 원하는 데이터를 함께 작성하여 넣어주면 된다. 후자에 전달된 데이터가 실제 채널 이벤트 핸들러에서 onWrite 메소드의 인자 중 세 번째로 전달되는 'Object Data’에 해당된다.

이후에는 ChannelEventManager의 postChannelEvent를 통해 채널 이벤트를 발생시킨다.

ChannelEventManager.postChannelEvent(ChannelEvent channelEvent, UserContext userContext)
매개변수 설명

channelEvent

발생시킬 채널 이벤트 객체를 전달한다.

userContext

이벤트 체인 내에서 공유되는 사용자 정보가 저장되는 저장소로, 발생된 채널 이벤트에서 참조할 현재의 이벤트 체인 사용자 정보를 전달한다.

4.2. 이벤트 연동

이벤트 핸들러에서 다른 이벤트를 발생시키려면 EventManager의 정적 메소드를 이용한다.

EventManager.postEvent(Event event)
매개변수 설명

event

발생시킬 이벤트 객체를 전달한다.

이때 발생시킨 이벤트가 현재 채널 이벤트의 처리 완료 이벤트라면 현재 처리 중인 이벤트를 발생시켰던 이벤트의 응답 이벤트가 되어 해당 이벤트 핸들러의 onResponseEvent 메소드가 호출된다. 그 외에는 새로운 이벤트가 발생되고, 해당 이벤트를 처리하는 이벤트 핸들러가 호출된다.

이벤트 핸들러에서 서비스를 연동할 때에는 일반적인 이벤트를 발생시키는 것과 동일하다.

ProObject에 미리 정의된 ServiceRequestEvent를 발생시켜 연동하고, 서비스의 응답이 돌아오면 ServiceResponseEvent 이벤트가 전달된다.

다음의 메소드를 사용해서 서비스 요청 이벤트를 생성시킬 수 있다.

ServiceRequestEvent(ServiceName serviceName, Object input)
매개변수 설명

serviceName

요청할 서비스의 이름을 지정한다.

input

서비스의 입력값을 전달한다.

이후 생성된 ServiceRequestEvent 객체에 서비스 요청에 필요한 값들을 각종 Setter를 이용하여 지정할 수 있다.

매개변수 설명

requestMessageType

서비스를 요청할 때 데이터를 어떤 형태로 변환할지를 지정한다.

  • ProMapperMessageType.NONE : 변환을 하지 않는다. (기본값)

  • ProMapperMessageType.JSON : 전달한 데이터가 JSON 문자열의 byte[] 인 경우 지정한다.

  • ProMapperMessageType.FLD: 전달한 데이터가 FixedLength의 byte[] 인 경우 지정한다.

  • ProMapperMessageType.XML : 전달한 데이터가 XML 문자열의 byte[] 인 경우 지정한다.

  • ProMapperMessageType.DELIMITER: 전달한 데이터가 Delimiter 문자열의 byte[]인 경우 지정한다.

responseMessageType

서비스의 응답을 전달할 때 데이터를 어떤 형태로 변환할지를 지정한다.

  • ProMapperMessageType.NONE : 변환을 하지 않는다. (기본값)

  • ProMapperMessageType.JSON : JSON 문자열의 byte[] 형태로 반환한다.

  • ProMapperMessageType.FLD: FixedLength의 byte[] 형태로 반환한다.

  • ProMapperMessageType.XML : XML 문자열의 byte[] 형태로 반환한다.

  • ProMapperMessageType.DELIMITER: Delimiter 문자열의 byte[] 형태로 반환한다.

requestContext

요청 정보를 변경한다. 이에 대한 자세한 내용은 Request Context를 참고한다.

이벤트 핸들러에서 타이머 이벤트를 발생시키는 경우 TimerSetupEvent 메소드를 사용해서 타이머를 요청할 수 있다. 지정한 시간이 지난 후에는 TimeoutEvent가 전달된다.

TimerSetupEvent(long timeout)
매개변수 설명

timeout

기다릴 시간을 밀리초(ms) 단위로 지정한다.

4.5. 이벤트 체인 종료

이벤트 핸들러 또한 채널 이벤트 핸들러와 동일하게 ChannelEventManager.endEvent를 호출하여 이벤트의 체인을 종료하는 것이 가능하다. 이에 대한 자세한 설명은 연동 종료를 참고한다.