UnityServer - Connector

k_hyun·2022년 11월 1일
0

Unity_Server

목록 보기
19/32

Connector.cs

서버와 서버를 연결할 수도 있기에 만든 스크립트이다.

클라와 서버 연결에도 사용 가능하다.

namespace SeverCore
{
    public class Connector
    {
        Func<Session> _sessionFactory;

        public void Connect(IPEndPoint endPoint, Func<Session> sessionFactory)
        {
            // 휴대폰 설정
            Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            _sessionFactory = sessionFactory;

            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            args.Completed += OnConnectCompleted;
            args.RemoteEndPoint = endPoint;
            args.UserToken = socket;

            RegisterConnect(args);
        }

기본적인 소켓을 설정하고 RegisterConnect 함수를 실행한다.

        void RegisterConnect(SocketAsyncEventArgs args)
        {
            Socket socket = args.UserToken as Socket;
            if (socket == null)
                return;

            bool pending = socket.ConnectAsync(args);
            if (pending == false)
                OnConnectCompleted(null, args);
        }

userToken으로 저장한 소켓을 가져와서 ConnectAsync를 실행한다.

        void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
        {
            if (args.SocketError == SocketError.Success)
            {
                Session session = _sessionFactory.Invoke();
                session.Start(args.ConnectSocket);
                session.OnConnected(args.RemoteEndPoint);
            }
        }
    }
}

Connect가 되면 실행되는 함수이다.

Connect되면 세션을 start하고 OnConnected 함수를 실행한다.

코드 이전

ServerCore의 Program.cs는 엔진이 아니라 컨텐츠 부분에 해당하는 스크립트이다.

따라서 이를 Server프로젝트의 Program.cs로 옮긴다.

이후 ServerCore 프로젝트는 클래스 라이브러리로 지정한다.

다른 프로젝트의 스크립트들을 참조하기 위해서 Server와 DummyClient 프로젝트에서 다음 설정을 한다.

이렇게 하면 ServerCore에서 작성한 코드들을 다른 프로젝트에서도 사용할 수 있게 된다.

Program.cs (DummyClient)

namespace DummyClient
{
    class GameSession : Session
    {
        public override void OnConnected(EndPoint endPoint)
        {
            Console.WriteLine($"OnConnected {endPoint}");

            // 보낸다
            for (int i = 0; i < 5; i++)
            {
                byte[] sendBuff = Encoding.UTF8.GetBytes($"hello World  {i}!");
                Send(sendBuff);
            }
        }

        public override void OnDisconnected(EndPoint endPoint)
        {
            Console.WriteLine($"OnDisonnected {endPoint}");
        }

        public override void OnRecv(ArraySegment<byte> buffer)
        {
            string recvData = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count);
            Console.WriteLine($"[From Server] {recvData}");
        }

        public override void OnSend(int numOfBytes)
        {
            Console.WriteLine($"Transferred bytes: {numOfBytes}");
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            // DNS (Domain Name System)
            string host = Dns.GetHostName();
            IPHostEntry ipHost = Dns.GetHostEntry(host);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

            Connector connector = new Connector();
            connector.Connect(endPoint, () => { return new GameSession(); });

            while (true)
            {               
                try
                {
                    
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }

                Thread.Sleep(1000);
            }
            
        }
    }
}

커넥터를 생성하여 Connect 함수를 실행한다.

이렇게 되면 Connect -> Start -> 리시버 등록 및 센더 등록 과정을 거친다.

실행

0개의 댓글