제2장 UCS 프로그램

내용 목차

2.1. 개요
2.2. UCS 프로그램 구성
2.2.1. 서버 프로그램
2.2.2. 클라이언트 프로그램
2.3. UCS 환경설정 및 컴파일
2.3.1. 환경설정
2.3.2. 컴파일

본 장에서는 UCS 프로그램 구성 및 환경설정 및 컴파일 방법에 대해 기술한다.

UCS(User Control Server)란, 프로그램의 처리 흐름을 미들웨어에서 제어하지 않고, 사용자가 직접 제어할 수 있는 Tmax 고유의 프로그램 형태이다. 이를 이용한 프로그램과 프로세스를 각각 UCS 프로그램 및 UCS 프로세스라고 한다.

클라이언트의 요청이 없어도 정보 전달이 필요한 업무(증권 시세 정보, notify 등), 작업 스케줄링 업무 및 대외기관과의 연동 업무 등에 UCS가 사용된다.

UCS 프로그램은 usermain()에 대한 구현부가 있어야 하고, 컴파일할 때 UCS 라이브러리(libsvrucs.a / libsvrucs.so)와 링크되어야 한다. 기본적으로 usermain()은 무한루프 형태로 구현된다. 즉, usermain()이 종료(함수 반환)되면, 해당 프로세스는 tpsvrdone()을 수행하고 종료하기 때문이다. usermain()은 main()이 종료되면 해당 프로세스가 종료되는 것과 같다.

주의

UCS 프로그램을 작성할 때는 tpschedule()을 통해 위 클라이언트로부터 전송된 데이터나 Tmax 커널로부터 전송된 종료 명령을 받기 때문에, usermain()의 무한루프 내에 tpschedule()가 항상 존재해야 한다는 것을 주의해야 한다.

다음은 특정 정보를 접속된 클라이언트에게 비요청 메시지 형태로 전송하는 usermain()의 간단한 예제이다.

+1   #include <stdio.h>
+2   #include <usrinc/atmi.h>
+3   #include <usrinc/ucs.h>
+4
+5   #define MAX_CLI 10
+6   int num_cli;
+7   int client_id[MAX_CLI];
+8   int count;
+9
+10  int
+11  tpsvrinit(int argc, char *argv[])
+12  {
+13    num_cli = 0;
+14    count = 0;
+15  }
+16
+16  int
+17  usermain(int argc, char *argv[])  /* Tmax의 ucs 모드에서 main과 같은 부분 */
+18  {
+19     int         jobs;
+20     int         i;
+21     int         ret;
+22     char        *sndbuf;
+23     static int count = 0;
+24
+25     printf("usermain start\n");
+26
+27     sndbuf = (char *)tpalloc("CARRAY", NULL, 1024);
+28    
+29     while(1) {
+30        for  (i = 0; i < num_cli; i++) {
+31                  sprintf(sndbuf, "Success tpsendtocli [%d] 012345678901234\n", 
                             count);
+32              tpsendtocli (client_id[i], sndbuf, 1024, 0); 
+33            }
+34            count++;
+35         sleep(1);
+36         jobs = tpschedule(-1);
+37     }
+38  }
+39 
+40  LOGIN(TPSVCINFO *msg) /* Tmax의 SERVICE 부분 */
+41  {
+42        char        *sndbuf;
+43        int         clid;
+44        int         ret;
+45        int         i;
+46        
+47        printf("msg->data = [%.*s]\n", msg->len, msg->data);
+48        fflush(stdout);
+49
+50        sndbuf = (char *)tpalloc("CARRAY", NULL, 1024);
+51        
+52        printf("Success transaction");
+53        sprintf(sndbuf, "Success transaction");
+54
+55        if (num_cli < MAX_CLI) {
+56            client_id[num_cli] = tpgetclid();
+57                printf("client id(clid) = %d\n", client_id[num_cli]);
+58                num_cli++;
+59        }
+60
+61        tpreturn(TPSUCCESS, 0, (char *)sndbuf, 1024, 0);
+62  }        

다음은 예제 프로그램에 대한 간략한 설명이다.

  1. 최초로 기동할 때 tpsvrinit()을 수행하고 usermain()으로 들어온다.

  2. 라인 30, num_cli값이 0이므로, for 문을 빠져나온다.

  3. 라인 36, tpschedule()을 통해 클라이언트로부터 서비스 요청이 있는지 또는 tmdown 명령을 받았는지 확인한다.

  4. 라인 40, 클라이언트로부터 LOGIN SERVICE 요청이 온 경우 수행한다. 요청이 없는 경우 tpschedule()을 빠져나온다.

  5. 라인 56, tpgetclid()를 통해 접속된 클라이언트 정보를 global(이하 전역) 변수인 client_id에 저장한 후 num_cli값을 증가시킨다.

  6. 라인 61, LOGIN SERVICE를 요청한 클라이언트에 응답 데이터를 전송한다.

  7. 라인 36, tpschedule()을 빠져나온다.

  8. 라인 30, num_cli값이 양수값이므로 for 문을 수행한다.

  9. 라인 32, tpsendtocli()를 통해 client_id에 저장된 클라이언트에 해당 정보를 전송한다(이 부분이 비요청 메시지를 전달하는 부분이다).

  10. 3 ~ 9 단계를 반복하여 수행한다.

  11. tpschedule()에서 tmdown 명령을 받았다면 tpsvrdone()을 수행한 후 프로세스가 종료된다.

UCS 서버 프로그램은 다음과 같은 모듈과 라이브러리로 구성된다.


위와 같이 UCS 프로그램은 1개의 모듈과 1개의 라이브러리로 구성되며, usermain()의 모듈 내에는 반드시 tpschedule()을 호출해야 한다.

UCS 프로그램은 위와 같은 프로그램 구성을 통해 사용자가 능동적으로 제어할 수 있고, 이를 이용해 다양한 업무를 수행할 수 있는 여러 가지 API를 제공한다. API의 프로토타입은 다음 경로에 정의되어 있다.

$(TMAXDIR)/usrinc/ucs.h

주요 API의 프로토타입은 다음과 같다. 각 함수에 대한 자세한 내용은 “제3장 UCS 함수”를 참고한다.

  • 모든 UCS 프로그램에서 사용되는 API

    • int tpschedule(int sec)

    • int tpuschedule(int usec)

  • 비요청 메시지 전송에 이용되는 API

    • int tpsendtocli(int clid, char *data, long len, long flags)

    • int tpgetclid(void)

  • Non-Tmax와의 비동기 통신을 위한 API

    • int tpsetfd(void)

    • int tpissetfd(void)

    • int tpclrfd(void)

    • int tpgetctx(CTX_T *ctxp)

    • int tpcancelctx(CTX_T *ctxp)

    • CTX_T *tpsavectx()

    • int tprelay(char *svc, char *data, long len, long flags, CTX_T *ctxp)

  • UCS 내에서 tpacall(비동기 통신) 함수를 사용할 때 이용되는 callback API

    • int tpregcb(void)

    • int tpunregcb(void)