[TIL] 20241218 TIL : 유니티 위치 동기화 w. SocketIO

Jaeyoung Ko·2024년 12월 18일
0

.NET 환경의 C# 서버를 구현하는 것은 아니지만,

비록 백엔드 부분이 nodejs와 socket.io를 이용하지만,

연동되는 클라이언트 파트는 C# 기반의 Unity 엔진이기 때문에, 멀티 쓰레드에 대한 고려가 필요하다.




<1> Node(JS) vs Unity(C#)


1) Single Thread의 Node.js


노드 환경은 기본적으로 싱글 스레드 기반으로 event loop와 비동기 I/O 모델을 사용한다.

따라서 async/await 구문을 중점적으로 간편하게 단일 스레드만 고려하여 개발을 진행하면 된다.


물론, 싱글 스레드란 구조적인 부분에서 기인하는 문제로 CPU를 많이 사용하는 계산량에 대한 성능 저하 가능성이 존재한다.


2) Multi Thread 환경의 C#


이와 달리 C# 은 멀티 스레드를 지원하는 환경으로, ThreadTask 를 이용하여 멀티 스레드를 사용 가능하여 병렬 작업을 진행할 수 있다.

대부분의 유니티 API는 main thread에서만 접근 가능하다.
즉, 유니티에서는 메인 쓰레드를 통해 단일 메인 로직을 구현하고,
Coroutine 을 통해 Thread의 개념을 수행한다.

즉, Coroutine을 통해 Unity API를 사용하며 비동기 병렬 처리할 수 있으나,
직접 Thread를 사용할 경우 Unity API는 사용이 불가하다.

// 전처리 쓰레드 네임스페이스
using System.Threading;

현재 쓰레드가 메인 쓰레드인지 확인하기

using System.Threading;

    private bool IsMainThread()
    {
        return Thread.CurrentThread.ManagedThreadId == 1;
    }

이런 쓰레드를 이용하여 CPU Bound Task들에 대해 병렬 처리를 통한 성능 향상의 장점을 얻을 수 있다.

다만, 역시나 Synchronization과 관련한 문제들이 주요 단점이다.




<2> EAP vs TAP


이와 관련해서 알아두면 좋은 내용이 바로 EAP와 TAP이다.

1) Event-based Asynchronous Programming (EAP)

.NET DOCS: EAP 링크

주로 이벤트, 델리게이트 모델을 사용하여 보류 중인 async 작업과 통신하는 모델이다.

EAP는 시스템의 흐름을 event란 독립적 동작으로 제어하는 패러다임으로, 보통의 게임에서는

상태변화, 유저 입력, 네트워크 요청과 같은 이벤트가 주요하다.

구현에 있어서 주로 *METHOD_NAME*Async 메서드, *METHOD_NAME*Completed 이벤트를 통해 Event Listener와 callback 함수로 이루어진다.


BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (sender, e) => {
    // 비동기 작업 실행
};
worker.RunWorkerCompleted += (sender, e) => {
    // 비동기 작업 완료 후 결과 처리
};
worker.RunWorkerAsync();


이벤트 발생 시마다 처리하는 방식으로 직관적인 구현이 가능하나,

콜백 함수들의 남용으로 콜백지옥과 같은 단점이 존재한다.



2) Task-based Programming (TAP)

.NET DOCS: TAP 링크

TAP의 비동기 메서드는 Task, Task<TResult>, ValueTaskValueTask<TResult>와 같은 대기할 수 있는 형식을 반환하는 메서드의 작업 이름 뒤에 Async 접미사를 포함한다.

즉, 간단히 말해 Task객체로 감싼 비동기 작업에 대해, asyncawait 키워드로 직관적으로 병령 처리를 한다.


C# 에서는 현대적인 비동기 프로그래밍 패러다임으로 TAP를 널리 사용하는 추세이다.

profile
안녕하세요, 고재영입니다. 언제나 즐겁게 살려고 노력합니다.

0개의 댓글