🌞 Listen의 반대 Connect
Listen의 반대편 개념인 Connect를 만들어주자.
기존에 Connect는 Client쪽에서 만들어 주었었다. 그런데 지금 만드는 것은 서버 쪽 Connect인데, 이건 왜 만드는 것인가 ?
서버가 꼭 하나라는 법이 없다. 하나의 게임에 여러개의 서버가 있을 수 있기 때문에 각각의 서버를 연결해줄 Connect가 필요한 것이다. 이것을 해주는 것이 Connector이다. 또한 ServerCore 부분은 클래스 라이브러리로 변경할 것이기 때문에, 이 Connector를 클라이언트 쪽에서 재사용 할 수 있다.
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ServerCore
{
public class Connector
{
Func<Session> _sessionFactory;
public void Connect(IPEndPoint endPoint, Func<Session> sessionFactory)
{
_sessionFactory = sessionFactory;
Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += OnConnectCompleted;
args.RemoteEndPoint = endPoint;
args.UserToken = socket;
RegisterConnect(args);
}
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);
}
void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
{
if (args.SocketError == SocketError.Success)
{
Session session = _sessionFactory.Invoke();
session.Start(args.ConnectSocket);
session.OnConnected(args.RemoteEndPoint);
}
}
}
}
Connect가 일어난 후 사후 처리를 위한 함수가 Session 쪽에 있기 때문에 sessionFactory가 존재한다. Connect 메소드가 실행 될 때, 이 sessionFactory에 실행부에서 등록한 session을 가져와 Connect가 끝날 때 Invoke하여 실행되게끔 해준다.
🌞 라이브러리화
다음 할 것은 ServerCore 부를 엔진부와 실행부로 나눌 것이다. 기존에 있었던 Server 프로젝트 부분이 실행부, ServerCore가 엔진부가 될 것이다. 그렇기 때문에 우리가 ServerCore에서 실행부로 적었던 Program class의 내용을 서버 프로젝트로 옮겨주어야 한다. 그러기 위해서는 ServerCore를 클래스 라이브러리화를 하고, Server 프로젝트에서 참조 클래스로 ServerCore를 등록하여야 한다.
위의 과정은 Client에서도 똑같다. Client에서는 ServerCore에 있는 Connector와 Session등을 재사용하기 위해서 ServerCore를 참조하여야 한다.