카테고리 없음

Unity 비동기 소켓 프로그래밍

Wood Pecker 2024. 6. 14. 13:27

 

1. 개요

    SocketIOClient를 사용하여  유니티 에디터에서 비동기 소켓 프로그램을 작성하고 테스트 하여본다. 

    [참고] 안드로이드 플랫폼에서는  동작이 안되는 것 같다.  맨 아래 후기 참조.

2. 유니티에 nuget 패키지 관리자  설치하기 

     Window 메뉴>Packet Manager
    좌측 상단 + 클릭하고 'Add package from git URL 선택

     https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity 
    입력하고 Add를 클릭하면 설치가 진행되고 설치가 완료되면 유니티 에디터에  NuGet 메뉴탭이 추가됩니다.

 

3. nuget을 이용하여 SocketIOClient 설치하기

     nuget을 실행하고 검색창에 SocketIOClient 검색하고 설치하기 버튼을 클릭한다.

     [추가]   Newtonsoft.json도 함께 설치한다. 

 

4. 스크립트 작성하기 

    유니티 Scene에서 Main Camera에  Add Compoent하기를 하여 MySocketIOClient.cs  스크립트를 아래와 같이 추가한다.  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SocketIOClient;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class MySocketIOClient : MonoBehaviour
{
    SocketIOClient.SocketIO socket;
    
    async void Start()
    {
        System.Net.ServicePointManager.SecurityProtocol = 
            System.Net.SecurityProtocolType.Tls12 | 
            System.Net.SecurityProtocolType.Tls11 | 
            System.Net.SecurityProtocolType.Tls;

        socket = new SocketIOClient.SocketIO("http://localhost:3000");
         Debug.Log("Start #1");
         socket.OnConnected += async (sender, e) =>
         {
              Debug.Log("OnConnected..");
        };

         await socket.ConnectAsync();   

         Debug.Log("Start #2");
         await SendMessage("student", "myroom/12345", "history", "history","unity useer");
    }

      public async Task SendMessage(string role, string room, string classId, string userId, string userName)
    {
        try
        {
            var message = new
            {
                role,
                room,
                class_id = classId,
                user_id = userId,
                user_name = userName
            };

            string jsonMessage = JsonConvert.SerializeObject(message);
            Debug.Log($"Sending message: {jsonMessage}");

            await socket.EmitAsync("create or join", jsonMessage);
            Debug.Log("Message sent successfully");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Error sending message: {ex.Message}");
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

5. node.js 의  server.js 서버 프로그램은 디음과 같이 작성한다.

const http = require('http');
const socketIo = require('socket.io');
const fs = require('fs');
const path = require('path');

// HTTP 서버를 생성합니다.
const server = http.createServer((req, res) => {
    // 간단한 HTML 파일을 제공하는 코드입니다.
    if (req.url === '/') {
        fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
            if (err) {
                res.writeHead(500);
                return res.end('Error loading index.html');
            }
            res.writeHead(200, { 'Content-Type': 'text/html' });
            res.end(data);
        });
    } else {
        res.writeHead(404);
        res.end('Not Found');
    }
});

// Socket.IO 서버를 HTTP 서버에 연결합니다.
const io = socketIo(server);

// 클라이언트가 접속하면 실행되는 이벤트 핸들러입니다.
io.on('connection', (socket) => {
    console.log('New client connected');

    // 클라이언트로부터 메시지를 받으면 실행되는 이벤트 핸들러입니다.
    socket.on('create or join', (message) => {
        console.log('Message received:', message);
        // 받은 메시지를 모든 클라이언트에게 브로드캐스트합니다.
        io.emit('message', message);
    });

    // 클라이언트가 연결을 끊으면 실행되는 이벤트 핸들러입니다.
    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });
});

// 3000번 포트에서 서버를 시작합니다.
const port = process.env.PORT || 3000;
server.listen(port, () => console.log(`Listening on port ${port}`));

 

 

유니티에서 서버로 메시지 전송이 되는지 확인한다. 

 

[추가]  SocketIOClient 를 사용한 위 코드는  유니티 에디터에서  https를 이용한 소켓통신을 하는데  연결이 안되고  reconnect만 반복되면서 실패를 하였다. 위에서 사용한 라이브러리가 security protocol을 지원한다고는 하는데  서버 설정을 바꾸어 보아도 도저히 연결이 안된다.  즉 https://server_url 와 같이 연결을 시도하였다. 파이썬 코드에서는서버  접속이 잘 된다. 서버 문제는 아닌다.  그러나 유니티 에디터에서는 안된다. 결국 nginx에서 proxy를 사용하여 redirect한 포토번호를 직접 이용하여 연결하였다.  즉  https가 아닌 http://server_url:6080 이런식으로 ... 하여야 했다. 또한 다음 단계로  유니티 에디터에서 안드로이드 프로젝트로 export하여 오큘러스에서 사용하려고 시도 하였다. 퍼미션을 아무리 수정해도 안드로이드에서는 위 방식도 연결이 안된다.  SocketIOClient는 안드로이드에서는 사용이 어려운것 같다. 결국 유료 Asset인 BestHTTP를 사용하였다. 

 

반응형