서버와 통신하기

이 장에서는 펑크랜드의 핵심 기능 중 하나인 서버와 메세지로 통신하는 기능에 대해서 알아봅니다.

FireEvent와 GetTopic의 이해


펑크랜드는 FireEvent와 GetTopic 메소드를 이용해 서버와 클라이언트간 통신을 지원합니다. 내부적으로 동작하는 방식은 GetTopic 메소드를 이용해 키와 함수를 등록 해 둔 뒤, 해당 키를 FireEvent로 호출하면 저장되어있던 함수를 호출하는 식으로 작동됩니다.

GetTopic은 특정 주제에 대한 이벤트를 처리하기 위해 사용되는 함수입니다. 이 함수를 사용하여 클라이언트에서 보낸 특정 Topic에 대한 이벤트를 처리할 수 있습니다. 예를 들어, "Apple"이라는 주제로 FireEvent를 발송했을 때, 해당 주제에 대한 이벤트를 처리하는 함수를 등록할 수 있습니다.

-- 클라이언트에서 "Apple" 이란 주제로 FireEvent를 발송했을 때
-- 모든 클라이언트들에게 "Apple" 이란 메시지 표시하기
Server.GetTopic("Apple").Add(function()
  Server.SendCenterLabel("Apple")
end)

Client.FireEvent("Apple")

GetTopicFireEvent를 사용하여 특정 주제에 대한 이벤트를 처리하고, 클라이언트에게 메시지를 전송할 수 있습니다. 반대로, 클라이언트에서도 GetTopic 메소드를 이용하여 이벤트를 처리할 수도 있습니다.

직렬화 문제


GetTopic과 FireEvent를 사용하여 통신할 때, 고급 개체의 직렬화는 지원되지 않습니다. 이는 Lua 스크립트에서 기본적으로 제공되는 기능이 아니기 때문입니다. 따라서, 고급 개체 혹은 타입을 직렬화하여 통신하는 경우에는 몇 가지 추가적인 처리가 필요합니다.

이를 위해, 펑크랜드에서는 Utility.JSONParse, Utility.JSONSerialize, 문샤프의 Json 라이브러리인 json.parse, json.serialize를 제공 하고 있습니다. Utility클래스의 Json메소드들도 내부적으로 문샤프의 Json 변환 라이브러리를 사용하고 있습니다.

1. string과 number 타입 처리

Lua스크립트의 string과 number타입은 별도의 추가적인 처리 없이 FireEvent를 이용해 전송할 수 있습니다.

아래는 string과 number타입을 서버로 전송하는 예시입니다.

Client.FireEvent("PlainData", "Hello", 1, 2, "World")

Server.GetTopic("PlainData").Add(function(...)
  print(...) -- Hello 1 2 World 출력
end)

2. table 타입 처리

테이블은 Lua에서 다양한 데이터를 저장하고 구조화 하는데 사용되는 유용한 데이터 구조입니다. 예를 들어, 테이블에 여러 개의 값을 저장하고 이를 직렬화 하여 FireEvent를 사용하여 전송할 수 있습니다.

아래는 테이블을 직렬화 하여 통신하는 예시입니다.

-- 클라이언트에서 테이블을 직렬화하여 FireEvent로 전송하기
local data = {name = "John", age = 25, score = 100}
local serializedData = Utility.JSONSerialize(data) -- 테이블을 직렬화하여 문자열로 변환

Client.FireEvent("TableData", serializedData) -- 직렬화된 데이터를 FireEvent로 전송

-- 서버에서 직렬화된 데이터를 받아 테이블로 변환하여 처리하기
Server.GetTopic("TableData").Add(function(serializedData)
  local data = Utility.JSONParse(serializedData) -- 직렬화된 데이터를 테이블로 변환
  print(data.name) -- "John" 출력
  print(data.age) -- 25 출력
  print(data.score) -- 100 출력
end)

위 예시에서는 테이블을 직렬화하여 문자열로 변환한 후, FireEvent로 전송합니다. 서버에서는 받은 직렬화된 데이터를 다시 테이블로 변환하여 처리할 수 있습니다. 이렇게 테이블을 직렬화 하여 통신하는 방법을 사용하면 고급 개체의 직렬화를 우회할 수 있습니다.

이 방법은 테이블과 같은 Lua의 기본 타입에만 적용됩니다. 펑크랜드에서 class형태로 제공하는 userdata타입은 직렬화 하지 못합니다. 만약 테이블 안에 다른 고급 개체가 포함되어 있다면, 해당 개체를 직렬화하고 통신하기 위해서는 개체의 속성을 개별적으로 추출하여 직렬화 해야 할 수 있습니다.

3. UserData 타입 처리

userdata타입은 속성을 개별적으로 추출하여 직렬화 해야 합니다. 이렇게 추출된 속성들을 테이블로 구성하여 직렬화 하고 통신할 수 있습니다.

-- 유닛 개체 가져오기
local me = Client.myPlayerUnit() 

-- 유닛 개체에서 필요한 속성을 테이블에 넣기
local serializedData = {
  name = me.name,
  exp = me.exp
}

-- 테이블을 직렬화하여 문자열로 변환
local serializedString = Utility.JSONSerialize(serializedData)

-- 직렬화된 데이터를 FireEvent로 전송
Client.FireEvent("UnitData", serializedString) 

-- 서버에서 직렬화된 데이터를 받아 유닛 개체로 변환하여 처리하기
Server.GetTopic("UnitData").Add(function(serializedString)

  -- 직렬화된 데이터를 테이블로 변환
  local unitData = Utility.JSONParse(serializedString) 
  print(unitData.name)
  print(unitData.exp)
  
  --
  -- 유닛 데이터 처리
  --
end)

위 예시에서는 유닛 개체 name, exp 속성을 추출하여 테이블로 구성한 후, 직렬화하여 통신합니다. 서버에서는 받은 직렬화된 데이터를 다시 테이블로 변환한 후, 유닛 개체의 속성에 할당하여 처리할 수 있습니다.

이렇게 테이블을 활용하여 고급 개체의 직렬화와 통신을 구현할 수 있습니다.

Last updated