0-2. 통신 규약 및 DB 테이블
미들웨어와의 통신 규약은 간단하게 전송할 데이터의 길이를 먼저 보내고 그 길이만큼 데이터를 전송하는 방식으로 개발한다. 전송 데이터의 첫번째 byte는 어떤 정보인지 확인 할 수 있는 구분자로 사용한다.
| 길이(Int64) = Length(구분자) + Length(데이터) | 구분자(1 byte) | 데이터 | 
길이와 구분을 제외한 데이터 부분은 간단하게 암호화를 해서 전송한다. 본강좌에 사용할 암호화는 예시를 들기위해 사용한, 복잡하거나 거창한게 아닌, 암호화라기보다는 중간에서 패킷을 가로챘을 때 바로 못 알아볼 정도의 난독화 수준이다. 실제 업무용으로 개발할 때는 각자가 알아서 좀더 정교한 암호화 방식을 사용하면 좋을 것이다.
  // 데이터 암호화
  procedure GP_SIMLazEnc(var AValue: TIdBytes);
  var
    i, l, x, k: Int32;
  begin
    l := Length(AValue);
    if l <= 0 then Exit;
    k := (l mod 100) + 21;
    for i := 0 to l - 1 do
    begin
      x := AValue[i] + k;
      if x > 255 then x := x - 256;
      AValue[i] := UInt8(x);
    end;
  end;
  // 데이터 해독
  procedure GP_SIMLazDec(var AValue: TIdBytes);
  var
    i, l, x, k: Int32;
  begin
    l := Length(AValue);
    if l <= 0 then Exit;
    k := (l mod 100) + 21;
    for i := 0 to l - 1 do
    begin
      x := AValue[i] - k;
      if x < 0 then x := x + 256;
      AValue[i] := UInt8(x);
    end;
  end;
미들웨어와 통신할 정보는 아래와 같이 로그인과 데이터 처리 및 버전을 확인하고 업그레이드 파일을 다운받는 정도의 최소한으로 정한다.(아래 표는 클라이언트 기준임.)
※ 전송 및 수신 데이터 항목에 사용된 "|" 기호는 프로그램 코드에서는 #9(tab) 값임.
| 구분자 | 내 용 | 전송 데이터 | 수신 데이터 | 
| A | 버전 정보 | 프로그램ID | 버전정보(ex: 1.0) | 
| B | 접속자 목록 | NULL | 사용자ID | 접속ID | 접속일시 | 
| C | 로그인 | 사용자ID | 암호(SHA256) | 관리자여부(1/0) | 사용자명 | 
| D | 데이터 가져오기(Open Query) | 요청 SQL | 반환 XML | 
| E | 데이터 처리(Execute Query) | 요청 SQL | 처리한 건수 | 
| F | 파일 다운로드 | 프로그램ID | 파일 데이터 | 
| X | Error(수신전용) | - | 에러메세지 | 
| Y | 접속응답(수신전용) | - | NULL | 
| Z | Dummy | NULL | NULL | 
클라이언트가 의도하지않게 죽을 경우 서버에 프로세스가 남아있을 수 있는데, 그것을 막기 위해 타이머를 이용해서 요청시간이 정해진 시간을 초과한 클라이언트를 제거한다. 클라이언트는 일정 시간마다 요청시간을 갱신해야하는데 아무런 처리 사항이 없을 경우 Dummy를 날려서 요청시간을 갱신한다.
본 강좌에서 테스트로 사용할 DB Table 정보는 아래와 같다.
/* 사용자 정보 */
CREATE TABLE slusrm
(
  usr_id               varchar(32) NOT NULL,         /* 사용자ID */
  usr_name             varchar(100) NOT NULL,        /* 사용자명 */
  passwd               varchar(128) NOT NULL,        /* 암호 */
  reg_date             date DEFAULT current_date,    /* 등록일 */
  admin_yn             char(1) DEFAULT '0' NOT NULL, /* 관리자여부 */
  use_yn               char(1) DEFAULT '1' NOT NULL, /* 사용여부 */
  remark               varchar(200),                 /* 비고 */
  CONSTRAINT pk_slusrm PRIMARY KEY ( usr_id )
);
INSERT INTO slusrm ( usr_id, usr_name, passwd, reg_date, admin_yn, use_yn )
VALUES ( 'ADMIN', '관리자', '8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918', current_date, '1', '1' ) ;
/* 버전 관리 */
CREATE TABLE slverm
(
  ver_id               varchar(16) NOT NULL,         /* Version ID */
  ver_major            integer NOT NULL,             /* Major Version */
  ver_minor            integer NOT NULL,             /* Minor Version */
  CONSTRAINT pk_slverm PRIMARY KEY ( ver_id )
);
/* Program Menu */
CREATE TABLE slmenum
(
  menu_id              varchar(16) NOT NULL,         /* Menu ID */
  up_id                varchar(16),                  /* 상위 Menu ID */
  menu_name            varchar(50) NOT NULL,         /* Menu Name */
  menu_yn              char(1) DEFAULT '1' NOT NULL, /* Menu 여부 */
  prg_id               varchar(200),                 /* Program ID */
  ord                  integer DEFAULT 1 NOT NULL,   /* 정렬순서 */
  CONSTRAINT pk_slmenum PRIMARY KEY ( menu_id )
);
/* 사용자별 Program Menu */
CREATE TABLE slmenut
(
  usr_id               varchar(32) NOT NULL,         /* 사용자ID */
  menu_id              varchar(16) NOT NULL,         /* Menu ID */
  auth_v               char(1) DEFAULT '0' NOT NULL, /* 조회권한 */
  auth_n               char(1) DEFAULT '0' NOT NULL, /* 등록권한 */
  auth_m               char(1) DEFAULT '0' NOT NULL, /* 수정권한 */
  auth_d               char(1) DEFAULT '0' NOT NULL, /* 삭제권한 */
  auth_p               char(1) DEFAULT '0' NOT NULL, /* 인쇄권한 */
  auth_a               char(1) DEFAULT '0' NOT NULL, /* 전체권한 */
  CONSTRAINT pk_slmenut PRIMARY KEY ( usr_id, menu_id )
);
CREATE INDEX idx_slmenut01 ON slmenut ( usr_id, menu_id ) ;
/* 기본코드(Major) */
CREATE TABLE slmajorm
(
  major_code           varchar(16) NOT NULL,         /* Major Code */
  major_name           varchar(50) NOT NULL,         /* Major Name */
  use_yn               char(1) DEFAULT '1' NOT NULL, /* 사용여부(0/1) */
  remark               varchar(200),                 /* 비고 */
  CONSTRAINT pk_slmajorm PRIMARY KEY ( major_code )
);
CREATE INDEX idx_slmajorm01 ON slmajorm ( use_yn, major_code ) ;
/* 기본코드(Minor) */
CREATE TABLE slminorm
(
  major_code           varchar(16) NOT NULL,         /* Major Code */
  minor_code           varchar(16) NOT NULL,         /* Minor Code */
  minor_name           varchar(50) NOT NULL,         /* Minor Name */
  use_yn               char(1) DEFAULT '1' NOT NULL, /* 사용여부(0/1) */
  remark               varchar(200),                 /* 비고 */
  CONSTRAINT pk_slminorm PRIMARY KEY ( major_code, minor_code )
);
CREATE INDEX idx_slminorm01 ON slminorm ( use_yn, major_code ) ;
로그인용 암호는 역함수가 없어도 되기때문에 SHA256을 사용한다.(※ ADMIN용으로 등록한 기초자료의 암호는 "admin" 임.)