[C# 서버] 소켓 프로그래밍 - Connector

이정석·2023년 8월 14일
0

CSharpServer

목록 보기
7/13

Connector

기존의 Connect는 블로킹함수로 Connect요청부터 연결이 완료될 때까지 요청한 쓰레드는 다른 연산작업을 할 수 없다. 이를 위해 비동기 Connect를 위한 Connector Class를 만들 필요가 있다.

Connector Class의 구조는 Listener Class와 비슷하다.

1. 서버에서의 Connect

서버에서 Connect를 한다는 것은 다른 호스트에 연결을 요청한다는 의미인데 '서버에서 연결을 요청할 일이 있을까?' 라고 생각할 수 있지만 다음과 같은 구조의 서버에서는 서버간의 Connect가 필요할 수 있다.

  1. 분산서버 환경의 서버간의 연결
  2. 프록시 서버
  3. 다중 데이터베이스 서버

2. ConnectAsync

ConnectAsync를 사용한 비동기 Connect를 구현하는 것은 Session의 Send를 구현한 것과 매우 유사한데 Connect변수, 인터페이스, 비동기 함수 호출, 콜백 함수를 구현하면 된다.

  • Connect과정 변수
	Func<Session> _sessionFactory;

Connect Class의 변수로는 Session을 생성하기 위한 팩토리 메서드가 필요하다. 실제 연결이 이루어 지고 어떻게 Session을 생성하는지는 나중에 설정하는 구조이다.

팩토리 메서드패턴이 생각나는 구조이다.

  • Connect 인터페이스
    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);
    }

외부에서 호출가능한 Connect 인터페이스로 Connect 요청을 위한 Socket, sessionFactory 설정, SocketAsyncEventArgs 설정, ConnectAsync 호출을 진행한다.

Session Class를 구현했을 때와 마찬가지로 Completed 이벤트의 콜백함수는 OnConnectCompleted로 하였다.

  • 비동기 함수 호출을 위한 Register
    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);
    }

ConnectAsync를 실행하는 RegisterConnect함수로 SocketAsyncEventArgs에 포함된 Socket을 통해 비동기 Connect을 시도한다.

만약 시간내에 Connect가 완료된다면 콜백함수를 직접 실행한다.

  • Callback함수 설정
    void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
    {
        if(args.SocketError == SocketError.Success)
        {
            Session session = _sessionFactory.Invoke();
            session.Start(args.ConnectSocket);
            session.OnConnected(args.RemoteEndPoint);
        }
        else
        {
            Console.WriteLine($"OnConnected Fail: {args.SocketError}");
        }
        
    }

Connnect가 완료되었을때 실행할 함수로 _sessionFactory로 Session을 생성한 뒤 연결된 소켓으로 Session을 설정한다. 설정을 끝냈다면 Session.OnConnected로 Connect된 후의 Session 이벤트를 실행시킨다.

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글