Chat 기능을 RPC 형태로 변경하고자 한다.
그런데 RPC가 필요한 상황으로부터 출발해보고 싶다.
Chat에 필요한 Client 함수 하나를 더 만들어봐야겠다.
사용자별 username을 설정하는 함수를 만들어야겠다고 생각했다. 이후 username을 만들어 서버에 전송해 다른 client에게도 뭔가 표시를 하고 싶은 상황에서 username의 내용을 서버로 보내야 할텐데, 서버로 보내는 데이터를 JSON으로 말아서 전달하면 관련된 라이브러리도 있고 파싱도 편할 것 같다는 생각이 들었다. 왜 JSON으로 데이터를 주고 받지 않는 걸까?
만약 username을 변경하는 함수에 대해 JSON으로 주고받는다고 생각해보면 아래와 같은 데이터 패킷을 만들 것이다.
// JSON text
{
function: "UpdateUserName",
username: "steelfox"
}
// JSON.stringify() 결과. 문자열 길이: 51
'{"function":"UpdateUserName","username":"steelfox"}'
간단히 작성해본 위 데이터 패킷의 길이는 51bytes이다. 데이터는 압축해서 많이 보낼수록 좋으니 함수명을 의미하는 부분의 "function":"UpdateUserName"
값을 약속된 더 짧은 문자열로 표현해볼 수도 있겠으나, 극단적으로 function
을 f
로 치환한다 하더라도 f
는 1byte이기에 8bits이다. 256가지 경우의 수를 더 만들어 압축하는 것도 가능한 것이다. 네트워크 패킷을 이용하면 bit 단위로 압축이 가능한 것이니, 문자열 그대로 전달이 되어야 하는 JSON을 사용하는 것보다 압축률이 더 높을 것으로 예상된다. 위 상황을 곧 구현해볼테니, 압축된 패킷 사이즈가 얼마가 되는지 비교해봐야겠다.
나의 의도는 UI Controller가 Button이 선택되었을 때의 이벤트를 받아서 처리하는 게 목표였다. 좋은 설계를 만드려면 Button은 UI Controller의 존재를 몰라야 할 것 같은데.. 아 그렇다기보다 Network 관련 코드와 Button의 코드를 분리한 게 이미 의미가 있다.
Button 및 동작 구현 - Text Mesh Pro - Button
동작을 구현하며, AddListener를 통해 callback 함수를 전달하는 코드를 확인했다. - delegate
UIController를 만들고, UIController에서 직접 다른 UI 요소들에 이벤트를 붙이고 제어하는 형태로 UIController만이 종속성을 갖도록 구현했다.
이제 이 함수를 서버에 전달해 서버에서도 username을 받아 변경점을 broadcast하는 코드를 만든다.
UI Controller의 무언가가 변경되어 Unity UI 상에서 Script에 연결해두었던 참조가 다 사라졌다.
이런 경우를 방지하기 위해서는 script 안에서 Component를 초기화 해주는 코드가 더 안전할 것 같다. 그런데 그렇게 하려니, Component를 FindAnyObjectByType()
과 같은 함수로 찾아야 한다. 이건 여러 개의 객체가 동일한 컴포넌트를 부착하고 있다면(clone된 경우) 찾는 과정에서 정확하게 그 객체!만 고르는 과정이 매끄럽지 않을 것이다. 그럴 것 같으면 Uniy Editor에서 주입해주는 게 더 좋은 것 같다.