/// <summary> /// 새로운 클라이언트가 접속 성공 했을 때 호출됩니다. /// AcceptAsync의 콜백 매소드에서 호출되며 여러 스레드에서 동시에 호출될 수 있기 때문에 공유자원에 접근할 때는 주의해야 합니다. /// </summary> /// <param name="client_socket"></param> void OnNewClient(Socket client_socket, object token) { // UserToken은 매번 새로 생성하여 깨끗한 인스턴스로 넣어준다. var uniqueId = MakeSequenceIdForSession(); var messageResolver = new TMessageResolver(); messageResolver.Init(ServerOpt.ReceiveSecondaryBufferSize); var user_token = new Session(true, uniqueId, PacketDispatcher, messageResolver, ServerOpt); user_token.OnSessionClosed += OnSessionClosed; SessionMgr.Add(user_token); // 플에서 하나 꺼내와 사용한다. SocketAsyncEventArgs receive_args = this.ReceiveEventArgsPool.Pop(); SocketAsyncEventArgs send_args = this.SendEventArgsPool.Pop(); receive_args.UserToken = user_token; send_args.UserToken = user_token; user_token.OnConnected(); BeginReceive(client_socket, receive_args, send_args); }
/// <summary> /// 원격 서버에 접속 성공 했을 때 호출됩니다. /// </summary> /// <param name="socket"></param> public void OnConnectCompleted(Socket socket, Session token) { token.OnSessionClosed += OnSessionClosed; SessionMgr.Add(token); // SocketAsyncEventArgsPool에서 빼오지 않고 그때 그때 할당해서 사용한다. // 풀은 서버에서 클라이언트와의 통신용으로만 쓰려고 만든것이기 때문이다. // 클라이언트 입장에서 서버와 통신을 할 때는 접속한 서버당 두개의 EventArgs만 있으면 되기 때문에 그냥 new해서 쓴다. // 서버간 연결에서도 마찬가지이다. // 풀링처리를 하려면 c->s로 가는 별도의 풀을 만들어서 써야 한다. SocketAsyncEventArgs receive_event_arg = new SocketAsyncEventArgs(); receive_event_arg.Completed += new EventHandler <SocketAsyncEventArgs>(ReceiveCompleted); receive_event_arg.UserToken = token; receive_event_arg.SetBuffer(new byte[1024], 0, 1024); SocketAsyncEventArgs send_event_arg = new SocketAsyncEventArgs(); send_event_arg.Completed += new EventHandler <SocketAsyncEventArgs>(SendCompleted); send_event_arg.UserToken = token; send_event_arg.SetBuffer(null, 0, 0); BeginReceive(socket, receive_event_arg, send_event_arg); }