방프리
21.03.27 Nodejs Socket.IO를 이용한 Unity 통신 (연결편) 본문
IOCP 등 소켓 통신을 공부하면서 웹 소켓 통신을 사용해보면 어떨까라는 호기심이 생겨 사용해보았다.
마침 회사에서 Nodejs를 사용해서 관련하여 공부할 겸 테스트를 해보기로 하였다.
일단 Nodejs를 세팅한 웹 서버의 정보는 다음과 같다.
운영체제 | Ubuntu 18.04 |
Nodejs | Nodejs 14.16.0 |
Socket.IO | 4.0.0 |
npm의 경우에는 따로 업데이트하지 않고 그대로 사용했다. Socket.IO 버전 관련해서 조사해보니 꽤나 많은 버전업이
있었는데 이 주기가 너무 짧아 사용 전 자기 버전의 가이드 문서를 반드시 한 번 확인해볼 필요가 있다.
SocketIO 주소 : socket.io/
Socket.IO
SOCKET.IO 3.0 IS HERE ~/Projects/tweets/index.js const io = require('socket.io')(80); const cfg = require('./config.js
socket.io
Unity 클라이언트에서 SocketIO를 사용하는 방법이라고 검색하다보면 반드시 이 에셋을 보게되는데
현재는 지원이 중단되었다. 물론 에셋 스토어에도 내려가있으니... 사용할 방법이 없다.
다른 방법으로는 C#의 Nuget Package를 이용하여 SocketIO 패키지를 이용하는 방법과 다른 유료에셋을
구매하는 방법밖에 없다. (위의 에셋이 유일하게 무료인 에셋이였다.)
필자는 이 에셋을 사용했다. 리뷰평도 굉장히 좋고 피드백이 굉장히 빠르다.
외국회사에 문의를 보내면 몇 일을 보고 기다려야 하는데 이 친구들은 거의 당일날 바로바로 처리해준다.
또한 어느정도 영어에 자신있다면 디스코드 서버도 있으니 참여해서 질문해도 된다.
일단 간단하게 Unity와 웹 소켓 서버가 통신하여 서로 로그가 남도록 해보자.
const socketIO = require('socket.io')(5000);
console.log('Server Start : port 5000');
// on은 클라이언트에서 보낸 이벤트를 실행할 때 사용
socketIO.on('connection', function(socket) {
console.log('Player Connected');
// emit은 클라이언트에 이벤트를 보낼 때 사용
socketIO.emit('PlayerConnected');
socketIO.on('disconnect', function() {
console.log('A Player disconnected');
});
});
웹 소켓 로직은 그다지 복잡하지 않다. 참고로 'connection', 'disconnection'과 같은 문자열들은 예약어이기 때문에
이벤트 문자열 작성 전에 확인하는 것이 좋다.
처음에 웹 서버를 열고 Unity가 아닌 브라우저를 통해 접속 확인을 하였는데 이부분에서 꽤나 삽질을 많이 했다.
결론적으로
- 1. 웹 소켓과 브라우저는 다르다. 애초에 브라우저를 통한 테스트 자체가 잘못된 방식
- 2. socket.listen() 함수는 불가능.... 꽤나 이전 블로그 등에서 require('socket.io').listen(port) 같은 코드가 보였는데 listen형태로 구축하는 것이 아님
- 3. 웹 소켓 서버가 제대로 열였는지 확인하려면 telnet을 이용하자
- 4. 3.0 버전부터 기본 url에 /socket.io/가 자동으로 붙는다. 자세한 내용은 다음 링크 참조 (socket.io/docs/v3/server-initialization/#path)
클라이언트 코드는 더 간단하다.
using BestHTTP.SocketIO3;
using BestHttP.SocketIO3.Events;
public class SocketClient : MonoBehaviour
{
[SerializeField] private string Address = "";
private SocketManager socketManager = null;
private void Start()
{
SocketIO3Connect();
}
private void SocketIO3Connect()
{
SocketOptions options = new SocketOptions();
options.AutoConnect = false;
socketManager = new SocketManager(new System.Uri(address), options);
socketManager.Open();
socketManager.Socket.On<ConnectResponse>(SocketIOEventTypes.Connect, OnConnected);
socketManager.Socket.On("PlayerConnected", PlayerConnected);
}
private void OnConnected(ConnectResponse res)
{
Debug.Log("Connected! Socket.IO");
}
private void PlayerConnected()
{
Debug.Log("Player Connected!!");
}
private void Destory()
{
if (this.socketManager != null)
{
this.socketManager.Close();
this.socketManager = null;
}
}
}
SocketOption을 통해 시작하자마자 바로 연결하는 설정을 끄고 Open()을 통해 소켓 연결을 하도록 한다.
socketManager.Socket.On 함수의 모습처럼 이벤트를 등록하고 소켓 서버와 통신하면서 해당 이벤트를 서로 실행하는
방식으로 통신이 된다. 웹 서버는 소켓 통신의 하위에 속하므로 BestHTTP 에셋 내부를 확인해보면
C#의 소켓통신이 사용됨을 확인할 수 있다.
서버 로그
클라이언트 로그
웹 소켓 서버가 워낙 쉬워서 비지니스 로직만 신경써도 괜찮아 편하다고 했는데 실제로 사용해보니 문법만 안다면
그다지 어려운 내용이 아니였다. 소켓 통신과 다르게 간단하게 몇 줄로 서버가 생성되고 연결되니 작업 속도는
확실히 향상될 것 같다. 하지만 메모리 누수 이슈나 Socket.IO가 너무나 빨리 버전업이 된다는 문제점이 있긴하다.
다음에는 캐릭터의 이동이나 인터렉션을 구현해보아야겠다.
'Server&Network > Node.js' 카테고리의 다른 글
21.04.10 Nodejs Socket.IO를 이용한 Unity 통신 (응용편) (0) | 2021.04.10 |
---|