클라이언트 플러그인

이번 장에서는 아이펀 엔진이 각 클라이언트 엔진 별로 제공하는 플러그인에 대해서 설명하고, 클라이언트 플러그인에서 사용되는 기본적인 개념에 대해서 알아보겠습니다.

개요

서버와 클라이언트가 네트워크상에서 서로 통신하기 위해서는 서버와 클라이언트 각각이 정해진 약속에 따라서 동작하는 네트워크 모듈을 구현해야합니다.

아이펀 엔진도 여러 편의 기능을 제공하기 위해서 독자적인 네트워킹 규약을 가지고 있기 때문에 네트워크 통신을 하기 위해서는 이 규약에 맞춰서 동작해야 합니다.

아이펀 엔진은 서버 구현 뿐 아니라 서버와 통신할 클라이언트의 네트워킹 기능을 담당하는 플러그인 모듈을 제공함으로써 네트워킹 기능의 구현에 드는 노력을 줄이고, 안정적인 네트워킹 기능을 제공합니다.

아이펀 엔진 클라이언트 플러그인이 지원하는 기능들은 다음과 같습니다.

  • 일반 메시지 송/수신

  • 멀티캐스트 메시지 송/수신

  • 공지사항 확인 기능

  • 리소스 다운로드 기능 등

현재 플러그인을 제공하는 클라이언트 엔진은 다음과 같습니다.

세션(Session)

아이펀 엔진의 세션(Session) 은 서버와 클라이언트 사이에 가상의 연결과 같습니다. TCP 나 UDP 같은 프로토콜 수준의 연결이 아니며 프로토콜보다 상위에 존재하는 개념입니다. 따라서 세션은 하나 이상의 네트워크 프로토콜을 동시에 사용할 수 있습니다.

가상의 연결이 필요한 이유는 모바일 네트워크는 그 특성 상 클라이언트와 서버 사이 연결이 자주 끊어지기 때문에 클라이언트가 새로 접속할 때마다 처리 비용이 비싼 로그인이나 사용자 데이터를 DB 에서 가져오는 동작을 반복하게 된다면 전체적인 서버의 성능을 떨어뜨리는 원인이 될 수 있습니다.

만약, 클라이언트와 서버 사이에 네트워크 연결이 끊어지더라도 서버에서 아이펀 세션 (이하 세션) 을 일정 시간동안 유지하고 있음으로써 클라이언트가 다시 접속했을 때, 이전의 클라이언트 정보와 연관 지을 수 있습니다.

세션은 서버 주도로 생성/삭제되며 클라이언트가 접속했을 때 사용 가능한 세션이 있다면 기존 세션을 사용하고 없다면 새로 생성합니다.

한번 생성된 세션이 서버 쪽에서 소멸되는 경우는 다음과 같습니다.

  • 서버에서 특정 세션에 대해서 Session::Close() 함수를 호출.

  • 클라이언트에서 Session::CloseRequest() 함수를 호출.

  • 클라이언트와 서버 사이에 설정한 시간 이상 메시지 송수신이 없어서 timeout 이 발생하는 경우.

클라이언트 플러그인에서 세션 객체는 세션 정보를 관리할 뿐 아니라, 세션 관련 옵션도 설정할 수 있습니다.

세션 객체는 트랜스포트 객체를 소유하는 것으로 연결 대상 서버와 TCP, UDP, HTTP, WebSocket 프로토콜 중 하나 이상을 사용할 수 있습니다. 이 때 세션 객체에 정의한 세션 관련 옵션은 여러 프로토콜을 사용하더라도 동일하게 적용됩니다.

반대로 하나의 세션 객체는 같은 프로토콜을 사용하는 트랜스포트를 중복해서 소유할 수 없습니다. 만약, 같은 연결 대상 서버에 대해서 같은 프로토콜을 여러 개 사용하고 싶다면 세션 객체를 별도로 생성해야 합니다.

Note

프로토콜과 포트는 Session::Connect() 할수를 호출할 때, 인자로 전달되고 세션 객체 하위의 트랜스포트 객체의 생성 인자가 됩니다.

아이펀 세션의 내부 구현 방식과 관련된 자세한 내용은 (고급) 아이펀 엔진의 네트워크 스택 에서 설명하고 있습니다.

세션 아이디

세션 아이디란

아이펀 엔진 서버는 세션을 구별하기 위해서 UUID 타입의 세션 아이디가 필요합니다. 클라이언트는 메시지에 세션 아이디를 함께 보냄으로써 서버가 세션을 식별할 수 있게합니다.

클라이언트에서 사용하는 세션 객체가 생성된 직후에는 세션 아이디가 정의되어 있지 않기 때문에 세션 아이디가 없는 메시지를 보내게 되는데, 이 때 서버는 새 세션을 생성하고, 세션 아이디를 클라이언트로 돌려줍니다.

세션 아이디를 돌려받은 클라이언트는 세션 객체에 저장하고, 이렇게 저장한 아이디는 세션 객체가 삭제될 때까지 클라이언트가 보내는 메시지와 함께 전송되어 서버가 세션을 구별하는데에 사용됩니다.

Note

클라이언트의 세션 객체에 설정된 세션 아이디는 서버 이동 기능을 사용할 때를 제외하면 객체가 사라질 때까지 변경되지 않습니다.

만약, 서버에서 세션을 닫아서 해당 세션을 더 이상 사용할 수 없는 경우에는 클라이언트도 기존 세션 객체를 삭제하고, 새 세션 객체를 생성해야 합니다.

이런 상황은 각 플러그인 별로 제공되는 세션 이벤트 핸들러 인터페이스를 통해서 제어할 수 있습니다.

세션 아이디 길이

세션 아이디는 플러그인에 의해서 자동으로 메시지에 삽입됩니다. 다만, 세션 아이디가 포함됨으로써 메시지의 전체 길이가 길어질 수 있기 때문에 메시지 인코딩에 따라서 세션 아이디의 표현 형식을 선택할 수 있습니다.

  • JSON 인코딩

    메시지에 JSON 인코딩을 사용하는 경우에 세션 아이디는 36 바이트 길이의 문자열로만 정의됩니다.

  • Protobuf 인코딩

    36 바이트 길이의 문자열 또는 16 바이트 배열 중에서 설정을 통해서 선택할 수 있습니다. 기본 동작에서 세션 아이디는 서버와 주고 받는 모든 메세지에 포함되므로, 길이가 짧은 16 바이트 배열를 사용하면 네트워크 사용량을 줄일 수 있습니다.

세션과 관련한 서버 쪽 설정

서버 쪽 설정 파일(MANIFEST.json)을 통해서 설정할 수 있는 세션과 관련한 옵션에 대해서 설명합니다.

  • send_session_id_as_string: 메시지 인코딩이 Protobuf 이면서 이 설정이 false 이면 세션 아이디를 바이너리 타입으로 전송하고, true 이면 문자열 타입으로 전송합니다. (type=bool, default=true)

  • send_session_id_only_once: 이 설정이 true 이면서 TCP 와 UDP 통신을 할 때, 세션 아이디를 첫 메시지에만 보내고 이후 메시지에서는 생략하여 메시지 크기를 작게 만들수 있습니다. (type=bool, default=false)

트랜스포트 (Transport)

클라이언트의 세션(Session) 을 생성할 때는 접속할 서버의 아이피(IP) 만을 설정하기 때문에 실제로 연결하기 위해서 프로토콜 수준의 설정이 필요합니다.

아이펀 엔진에서는 트랜스포트(Transport) 를 통해서 엔진이 지원하는 프로토콜 종류를 결정할 수 있습니다.

트랜스포트는 독립적으로 생성되지 않고, 세션이 여러개의 트랜스포트를 소유하며, 하나의 트랜스포트는 프로토콜, 포트, 메시지 인코딩과 같은 속성을 가집니다.

아이펀 엔진 트랜스포트가 지원하는 프로토콜을 다음과 같습니다.

  • TCP

  • UDP

  • HTTP

  • WebSocket

Important

하나의 세션은 각 프로토콜을 하나씩만 사용할 수 있습니다. 예를들어 TCP 연결이 맺어져 있다면(TCP 트랜스포트가 있다면) TCP 연결을 추가하기 위해서는 새로운 세션 객체를 생성해야 합니다.