본문 바로가기
UNITY/유니티게임스쿨

Unity 비동기 프로그래밍 :: Node.js 설치, 간단한 비동기 서버 구축

by 램플릿 2024. 6. 7.

 

Node.js 설치하기


 

nodejs 홈페이지에서 설치파일 다운로드 후 실행!
Next..Next..Next...
Install Chocolatey를 추천!
Finish

 

Enter 입력하면 Chocolatey도 설치 완료~~
윈도우키+R > cmd > 설치 버전 확인해보기

 

 

+ 토터스깃(tortoiseGit)도 설치 (소스트리, 깃허브데스크탑 등)

 


 

 

네트워크 프로그래밍 맛보기


 

express 프레임워크를 사용하여 간단한 HTTP 서버 설정하기 (비동기 서버 구축)

Node.js와 npm(Node Package Manager)이 설치되었다면 npm패키지에 있는 restAPI 구조의 express 프레임워크를 사용해볼 수 있다.

 

 

VSC(Visual Studio Code) > Terminal > New Terminal

 

 

JS로 간단한 REST API 서버 만들기

  • 터미널을 열어서 터미널 콘솔창에 명령어를 입력한다.
  • npm init > 엔터..엔터...엔터... > package.json 생성
  • npm i express > node_modules 생성
  • 마우스 오른쪽버튼 > New File... > index.js 파일 생성
const express = require('express');
const app = express();
const port = 3000;

//JSON 바디 파서를 추가
app.use(express.json());

//기본 라우트
app.get('/', (req, res) => {
	res.send('Hello World!');
});

//POST 요청을 처리하는 라우트
app.post('/data', (req, res) => {
	const data = req.body;
    console.log('Received data:', data);
    res.send('Data received successfully');
});

//서버 시작
app.listen(port, () => {
	console.log('Server is running on http://localhost:${port}');
});

 

 

노드 서버 실행 명령어

  • node index.js
  • ctrl+C : 실행 종료

 

+) 자동 저장 방법 :: npm i nodemon 설치 후

package.json 파일 > "scripts" 부분에 아래와 같이 "start:dev"을 추가

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start:dev" : "nodemon index.js"
  },

 

 

로컬 주소 접속하기

url에 http://localhost:3000/ 입력하여 접속

 

localhost == 127.0.0.1 , 즉 내 아이피를 말함.

동일 아이피에서 서버를 3개 열더라도 포트 번호를 다르게 해서 구분할 수 있다.

 

 

Postman을 통해 결과 살펴보기

postman 다운로드 링크
https://www.postman.com/downloads/?utm_source=postman-home

 



npm run start:dev

 

Tip👍쿼리 스트링
URL에서 ?는 쿼리 스트링(Query String)의 시작을 나타냅니다. 쿼리 스트링은 URL에서 서버로 전달되는 추가 데이터를 포함하는 부분입니다. 쿼리 스트링은 ?로 시작하고, 그 뒤에 키=값 형태의 쌍이 옵니다. 여러 쌍이 있을 경우, 앰퍼샌드(&)로 구분됩니다.

 

 

 


 

Unity 비동기 프로그래밍


 

비동기 프로그래밍

유니티에서 비동기 프로그래밍은 성능 저하를 방지하고, 긴 작업을 병렬로 실행하여 게임의 프레임 속도를 유지하는 데 사용됩니다.

 

 

코루틴 Coroutine

  • 유니티에서 가장 일반적으로 사용되는 비동기 프로그래밍 방식
  • StartCoroutine() 메서드를 사용하여 시작
  • IEnumerator를 반환
using System.Collections;
using UnityEngine;

public class CoroutineExample : MonoBehavior
{
	void Start()
    {
    	//코루틴 시작
    	StartCoroutine(ExampleCoroutine();
    }
    
    IEnumerator ExampleCoroutine()
    {
    	//2초 대기
        yield return new WaitForSecond(2);
        
        //메시지 출력
    	Debug.Log("2 seconds have passed.");
    }
}

 

 

Async과 Await

  • C# 7.0부터 지원되며 비동기 메서드를 정의 및 호출하는데 사용되는 키워드
  • 유니티에서도 이 기능을 사용할 수 있지만, 유니티 API는 대부분 메인 스레드에서만 호출될 수 있으므로 주의가 필요!
using System.Threading.Tasks;
using UnityEngine;

public class AsyncAwaitExample : MonoBehavior
{
	async void Start(){
    	//비동기 메서드 호출
        await ExampleAsyncMethod();
        Debug.Log("Async method completed.");
    }
	
    async Task ExampleAsyncMethod()
    {
    	//2초 대기
        await Task.Delay(2000);
    }
}

 

💡질문 :: 코루틴과 어싱크 비동기 방법은 무엇이 다른가요?
⇒ coroutine은 비동기처럼 쓸 수 있고, 유니티에서 관리하므로 버그가 잘 없습니다. (사실 coroutine은 스케줄링을 통해 비동기처럼 보이게 하는 싱글 스레드입니다.)
사용 용도 : Update() 대신 자신이 정한 주기에 따라 별도의 로직을 실행시키고 싶을 때, 일회적으로 사용하고 싶을 때 coroutine을 이용합니다. 네트워크 프로그래밍도 물론 가능합니다.

⇒ async/await는 유니티가 아닌 C#의 공식지원이기 때문에 멀티스레드에 친절하지 않은 유니티에서는 크래시가 나거나 데이터가 꼬일 수 있어 잘 추천되지 않습니다. 하지만 네트워크 프로그래밍같은 경우는 데이터를 주고 받는 것을 기다려야 하기 때문에 async/await를 많이 사용합니다.
사용 용도 : 네트워크 프로그래밍, 방대한 양의 데이터 처리 등을 비동기로 처리.

 

 

UnityWebRequest로 비동기 요청하기

유니티에서 웹 요청을 비동기로 수행하는 예제.

UnityWebRequest를 사용하여 서버로부터 데이터를 비동기로 가져옵니다.

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class WebRequestExample : MonoBehavior
{
	void Start()
    {
    	//코루틴 시작
        StartCoroutine(GetRequest('http://localhost:3000/data'));
    }
    
    IEnumerator GetRequest(string uri)
    {
    	using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
        {
        	//요청 전송
        	yield return webRequest.SendWebRequest();
            
            if (webRequest.result == UnityWebRequest.Result.ConnectionError)
            {
            	Debug.LogError("Error: "+webRequest.error);
            }
            else
            {
            	//요청 성공
            	Debug.Log("Response: "+webRequest.downloadHandler.text);
            }
    	}
	}
}