공지사항 서비스

게임 내에서 모든 사용자에게 노출해야 하는 공지사항이나 이벤트 같은 정보를 게시물 형태로 관리하고, 클라이언트 플러그인을 통해서 읽어들일 수 있는 기능을 제공합니다.

이 기능은 게임서버와는 별도로 Python Django 기반의 웹 어플리케이션 형태로 제작되었으며 iFun Announcer 라는 이름의 Docker 이미지로 제공합니다.

게임 운영자가 iFun Announcer 에 관리자 권한으로 게시물을 등록해 놓으면, 아이펀 엔진의 클라이언트 플러그인이 iFun Announcer 로부터 직접 공지 목록을 받아가는 방식으로 동작합니다.

iFun Announcer 설치

Caution

리눅스를 Docker 호스트로 사용하는 경우를 기준으로 기술되어 있습니다.

먼저, 공지사항 서비스를 사용하기 위해서는 iFun Announcer 서비스를 설치하고 실행해야 합니다.

iFun Announcer 서비스를 설치하고 실행하는 방법에 대해서 순서대로 설명하겠습니다.

준비하기

설치하기에 앞서 설치 과정에 필요한 몇가지 사항들에 대해서 확인해 보겠습니다.

MySQL

먼저, 게시물을 저장할 MySQL Database 가 필요합니다.

게시물을 저장할 Database 를 생성하고, MySQL 사용자에게 이 Database 에 대한 접근 권한을 설정해 주세요.

Warning

접근 권한을 설정하기 위해서는 MySQL root 사용자로 접속해야 합니다.

-- Database 생성.
-- MY_DB 를 원하는 이름으로 변경.
mysql> create database 'MY_DB';
Query OK, 1 row affected (0.00 sec)

-- MY_USER 라는 MySQL 사용자를 생성하면서, 패스워드를 MY_PASS 로 설정.
-- @'%' 는 사용자의 접속 위치를 지정하는 설정인데,
-- Docker 는 외부 호스트로 취급하기 때문에 @localhost 는 안됨.
mysql> create user 'MY_USER'@'%' identified by 'MY_PASS';
Query OK, 0 rows affected (0.00 sec)

-- 위에서 생성한 MY_USER 사용자에게 MY_DB 라는 Database 에 대한 접근
-- 권한을 부여.
mysql> grant all privileges on 'MY_DB'.* to 'MY_USER'@'%' with grant option;
Query OK, 0 rows affected (0.00 sec)

Docker 이미지 생성

iFun Announcer 를 실행하기 위해서는 Docker 이미지가 호스트에 있어야 하는데, 여러분의 호스트에 Docker 이미지를 생성하기 위한 방법은 두 가지가 있습니다.

  1. Docker Hub 서비스를 사용하는 방법.

  2. 파일로부터 직접 생성하는 방법.

여기서는 1. Docker Hub 서비스를 사용하는 방법 에 대해서만 설명하겠습니다.

Important

Docker 엔진은 docker-io 가 아닌 docker-ce 버전을 사용해야 합니다.

사용하시는 OS 의 패키지 매니저 또는 Docker 설치 매뉴얼(영문) 를 참고하여 설치를 진행해 주시기 바랍니다.

Note

파일로부터 직접 생성하는 방법의 경우는 이미지를 압축한 tar 파일이 필요합니다. iFun Engine support 로 요청해 주시기 바랍니다.

다음 명령을 실행하면 Docker Hub 저장소로부터 iFun Announcer Docker 이미지를 다운(pull) 받아서 호스트에 저장합니다. 만약, 파일로부터 직접 생성하는 경우는 이미지를 압축한 tar 파일이 있는 경로에서 docker load -i funapi-announcer.tar.gz 명령을 실행해 주세요.

~$ docker pull ifunfactory/funapi-announcer
Using default tag: latest
latest: Pulling from ifunfactory/funapi-announcer
976a760c94fc: Pull complete
c58992f3c37b: Pull complete
0ca0e5e7f12e: Pull complete
f2a274cc00ca: Pull complete
078c4e7bab57: Pull complete
40c1d89f64df: Pull complete
0ab1dc522c82: Pull complete
e9c68f105dca: Pull complete
98c929859046: Pull complete
2844442010bb: Pull complete
dc092a60b666: Pull complete
47d7174969ee: Pull complete
e450ef18c621: Pull complete
Digest: sha256:ea72e76c841f65c282cd9d5383cfc8f5be65de8908db9451b839e7ecbf081c65
Status: Downloaded newer image for ifunfactory/funapi-announcer:latest
docker.io/ifunfactory/funapi-announcer:latest

~$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
ifunfactory/funapi-announcer   latest              da8ce239e6c3        7 weeks ago         263MB

자, iFun Announcer 를 실행하기 위한 Docker 이미지가 준비됐습니다.

홈디렉터리 생성

iFun Announcer 서비스의 홈디렉터리로 사용할 디렉터리가 필요합니다. 이 디렉터리에는 iFun Announcer 서비스 설정과 데이터를 저장합니다.

여러분이 사용할 호스트의 임의의 경로에 announcer 디렉터리를 만들고, 서비스의 홈디렉터리로 사용하겠습니다.

그리고, 그 안에 settings 디렉터리와 images 디렉터리를 만들어주세요.

~$ mkdir -p announcer/settings announcer/images
~$ tree announcer
announcer
├── images
└── settings

사용자의 홈디렉터리에 임의의 디렉터리를 만들고, 그 안에 __init__.py 파일과 local.py 파일을 생성하고, 그 중 local.py 파일에는 다음 내용을 입력해 주세요.

# vim: set fileencoding=utf-8
# filename: local.py

from announcer.settings import *

DEBUG = False

# 수정하지 않아도 됩니다.
ALLOWED_HOSTS = ['*']

# 터미널에서 'openssl rand -hex 48' 명령을 실행한 결과를 아래 문자열에 입력합니다.
SECRET_KEY = ''

# 데이터베이스 연결 문자열을 채워 넣습니다.
# MY_DB, MY_USER, MY_PASS: 준비하기->MySQL 챕터에서 생성했던 MySQL 정보.
# IP_ADDR: MySQL 서버의 IP 주소.
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'MY_DB', # MySQL DB 이름
    'USER': 'MY_USER',    # MySQL 사용자
    'PASSWORD': 'MY_PASS',  # MySQL 패스워드
    'HOST': 'IP_ADDR', # MySQL 호스트의 docker network interface  주소
    'OPTIONS': {
        'charset': 'utf8mb4',
        'init_command': 'SET default_storage_engine=INNODB, character_set_connection=utf8mb4, collation_connection=utf8mb4_unicode_ci, sql_mode="STRICT_TRANS_TABLES"'
    }
  }
}

여기까지 진행하셨다면, iFun Announcer 를 초기화하고 실행하기 위한 준비 작업이 끝났습니다.

서버 인증서 설정

iFun Announcer 는 웹 어플리케이션이기 때문에 HTTPHTTPS 두가지 프로토콜을 사용할 수 있습니다.

여기서 설명하는 내용은 iFun Announcer 에 요청을 보낼 때, HTTPS 를 사용하기 위한 준비 단계이며, 개발 과정에서 HTTP 프로토콜을 사용해도 되는 단계에서는 생략해도 됩니다.

Important

라이브 환경에서는 반드시 HTTPS 프로토콜을 사용해 주시기 바랍니다.

  1. 먼저, 서버 인증서를 발급 받아야 합니다. 무료로 인증서를 발급해 주는 서비스가 많이 생겨서 인증서를 발급 받는데에 대한 비용은 부담이 없어졌지만, 서버 인증서를 발급받기 위해서는 대부분 도메인이 필요합니다.

  2. 다음으로 인증서를 저장할 디렉터리를 생성합니다. 앞서 사용했던 iFun Announcer 서비스의 홈디렉터리를 사용하겠습니다.

    ~$ mkdir -p announcer/cert
    ~$ tree announcer
    announcer/
    ├── cert
    ├── images
    └── settings
    
  1. 서버 인증서와 중간 단계 인증서를 합쳐서 announcer/cert/fullchain.pem 으로 저장합니다.

  2. 서버 비밀키를 announcer/cert/privkey.pem 으로 저장합니다.

초기화

iFun Announcer 의 초기화는 어플리케이션을 실행하기 전에 먼저 DB 를 초기화 하고, 관리자 계정을 만드는 단계입니다.

아래 명령에 있는 다음 문자열을 여러분의 환경에 맞게 수정해서 실행해 주세요.

  • SETTINGS_DIR: 앞에서 생성한 iFun Announcer 홈디렉러티 밑의 settings 디렉터리의 절대 경로입니다. (예: /home/USER/announcer/settings)

~$ docker run -it --rm \
  -v SETTINGS_DIR:/var/lib/funapi-announcer/settings \
  funapi-announcer:1.0.0 init

... 과정 생략 ...

Username (leave blank to use 'master'): xxxxx
Email address: xxxx@xxxxx.xxx (생략 가능)
Password:
Password (again):
Superuser created successfully.

iFun Announcer 실행

이제 iFun Announcer 를 실행해 볼 차례입니다.

iFun AnnouncerDocker 이미지의 실행 옵션에 따라 HTTPHTTPS 프로토콜을 구분해서 사용할 수 있습니다.

각 모드의 실행 명령 중 다음 문자열을 여러분의 환경에 맞게 수정해서 Docker 이미지를 실행해 주시기 바랍니다.

  • ${SETTINGS_DIR}: 앞에서 생성한 iFun Announcer 홈디렉러티 밑의 settings 디렉터리의 절대 경로입니다. (예: /home/USER/announcer/settings)

  • ${IMAGES_DIR}: iFun Announcer 홈디렉터리 밑의 images 디렉터리의 절대 경로입니다. (예: /home/USER/announcer/images)

  • ${SERT_DIR}: iFun Announcer 홈디렉터리 밑의 cert 디렉터리의 절대 경로입니다. (예: /home/USER/announcer/cert)

  • ${ANNOUNCER_HOSTNAME}: iFun Announcer Docker 이미지를 실행하는 호스트의 도메인명 또는 IP 주소입니다. HTTP 오쳥을 보낼 때 주소로 사용되는 문자열과 같아야 합니다. (예: example.ifunfactory.com 또는 192.168.1.100)

HTTPS 모드

iFun AnnouncerHTTPS 프로토콜로 동작하며, 서버 인증서 설정이 잘 못 된 경우 서비스를 정상적으로 사용할 수 없습니다.

라이브 서비스에서 사용하기 적합합니다.

~$ docker run -d --restart=always \
     --name=funapi-announcer \
     -e NGINX_SERVERNAME=${ANNOUNCER_HOSTNAME} \
     -p 80:80 \
     -p 443:443 \
     -v ${SETTINGS_DIR}:/var/lib/funapi-announcer/settings \
     -v ${IMAGES_DIR}:/var/lib/funapi-announcer/images \
     -v ${CERT_DIR}:/etc/nginx/announcer-cert \
     ifunfactory/funapi-announcer

HTTP 모드

iFun AnnouncerHTTP 프로토콜을 사용하며, 관리자가 로그인할 때 암호가 노출될 수 있는 등 보안에 취약하기 때문에 라이브 서비스에서는 사용하지 않도록 주의 하시기 바랍니다.

~$ docker run -d --restart=always \
     --name=funapi-announcer \
     -p 80:80 \
     -v ${SETTINGS_DIR}:/var/lib/funapi-announcer/settings \
     -v ${IMAGES_DIR}:/var/lib/funapi-announcer/images \
     ifunfactory/funapi-announcer unsecure

별다른 오류 메시지 없이 서버가 시작되었다는 메시지가 출력되면 iFun Announcer 가 정상적으로 시작된 것이므로 관리자 페이지에 접속해 보겠습니다.

웹 브라우저를 실행해서 주소창에 http(https)://{서버 아이피 주소 or 도메인 이름}/admin 을 입력하고 접속해 주시기 바랍니다.

아래와 같은 화면이 나오면 초기화 에서 입력한 Username 과 Password 를 입력해 주세요.

_images/announcer_login01.png

게시물 관리

관리자로 로그인하면 첫 화면에 Announcements 라는 메뉴가 있습니다. 이 메뉴에서 모든 게시물을 추가/삭제하거나 수정할 수 있는 메뉴입니다.

첫화면에서 Announcements->Add 또는 Annoucements 를 선택해서 들어가면 오른쪽 상단에 있는 ADD ANNOUNCEMENT + 버튼으로 공지사항을 등록할 수 있습니다.

_images/add_announcement01.png
  • Subject: 게시물의 제목입니다.

  • Message: 게시물의 내용입니다. 여기에 입력한대로 클라이언트가 전달받기 때문에 순수 문자열을 사용해도 되고 JSON 과 같이 형식이 있는 문자열도 사용할 수 있습니다.

  • Image: 게시물과 함께 이미지를 업로드합니다. 클라이언트 플러그인을 통해서 메시지와 함께 받아서 사용할 수 있습니다.

  • Link url: 게시물과 관련한 URL 정보 필드입니다. (자동으로 연결되지는 않습니다.)

  • Extra: Message 필드와 별도로 클라이언트에 전달되는 문자열입니다. Message 필드와 마찬가지로 형식이 정해져 있지 않습니다.

  • Kind: 게시물을 분류하기 위한 필드입니다. Kind 를 추가하기 위한 방법은 다음 챕터에서 설명합니다.

  • Extra image 0~4: 추가 이미지를 업로드 합니다.

게시물 분류(Kind) 추가

관리자 페이지에는 또한 Announcement kinds 라는 메뉴가 있습니다. 여기에서 게시물 분류(Kind) 를 관리하실 수 있습니다.

오른쪽 상단의 ADD ANNOUNCEMENT KIND + 버튼으로 게시물 분류를 추가할 수 있고, 상세 페이지에서는 삭제도 가능합니다.

_images/add_kind02.png

분류를 등록할 때, namedescription 를 입력할 수 있습니다.

_images/add_kind01.png
  • name (필수) : 실제로 사용할 분류 이름으로 191 자 이하의 문자열로 작성할 수 있습니다. 실제로 플러그인 등에서 사용할 문자열이니 주의깊게 설정해 주셔야 합니다.

  • description (생략 가능) : 해당 분류에 대한 설명 및 코멘트 등을 입력하는 필드이며, 입력 길이에 제한은 없습니다. 관리자 UI 에서만 사용하는 필드입니다.

분류를 등록한 이후에는 공지사항을 작성/수정 하실 때 해당 분류(kind)로 설정할 수 있습니다.

공지 등록시 분류(kind)를 --------- 로 설정하시면 미분류 공지사항으로 취급합니다.

클라이언트 코드

클라이언트에서 게시물을 가져와서 활용하는 예제는 Client Plugin 프로젝트의 소스코드를 참고해 주시기 바랍니다.

자세한 내용은 플러그인의 공지사항 메시지 를 참고해 주시기 바랍니다.