perpet

1년동안 다른거 공부하랴 c# 게임서버에 신경을 못쓰고 있네요.

간단하게 제가 제시하는 코딩방식은 이렇습니다.

 

예를 들어 설명하자면 유저가 로그인하여 아이디와 패스워드를 검증하는 코딩을 짠다고 봅시다.

보통 디비쿼리시 디비에 쿼리를 날리는순간 블럭이 되여 이것을 비동기 처리합니다.

그래서 코드가 보통이렇게 되죠.

 

void login_packet(string id, string pass)

{

int x;

db.query_login(id,pass,query_resultLogin) ; // 쿼리 결과 핸들 등록

return;

}

 

void query_resultLogin(int ret)

{

   if( ret == 0)   // 결과에 따라 처리

 

   client.send_login_result(ret) ;

 

}

 

이걸 c# 에서 yield 를 이용한 코딩을 하면 간단하게

 

void login_packet(string id, string pass)

{

int x;

yield db.query_login(id,pass) ;

 

  if( ret == 0)   // 결과에 따라 처리

 

   client.send_login_result(ret) ;

}

 

이렇게 표현될수있다는겁니다.

이런구조의 장점을 들어보자면

  1.  함수하나의 스코프안에서 원하는 구현부위를 표현하여 직관적입니다.
  2. 원시적인 비동기콜방식으로 할경우 쿼리 전 변수가 쿼리결가후에도 필요하면 해당변수를 외부에 저장할 글로벌 변수로 만들어야합니다. 위에 x 라는 변수가 쿼리 결과에서도 참조가 필요한 케이스가 발생할경우..( yield 를 하면 필요가 없겠죠)
  3.  명시적인 리모트 함수선언을 할수있습니다. 지금까지는 일반적인 패킷함수를 표현하면 void login(id,pass)  를 표현하면 알아서 loing 패킷을 만들어주고 send 함수를 만들어주는 수준이지만 yield  구조를 갖으면 리턴받아야하는 패킷도 명시적으로 표현할수있습니다.  가령 int query_login(id,pass) 라고 패킷을 선언하면 컨텐츠코딩단에서 해당하는 query_login 결과값이 올때까지 다른핸들링이 작동을 안하도록 할수있습니다. 또한 요청을 수행하는 디비단이나 다른서버가 다른형식의 패킷을 보내면 시퀀스를 어겼다고 네트웍시스템이 감지할수있습니다.

     

구체적인 구조를다시 만들면

 

server 인터페이스 선언에

int login_packet(string id,string pass) ;  를 선언하고

 

int login_packet(string id, string pass)

{

int x;

yield db.query_login(id,pass) ; <= db 에 쿼리를 날리고 올때까지 알아서 기다려줌(그동안 다른 클라이언트핸들링은 처리됨)

 

  if( ret == 0)   // 결과에 따라 처리

 

yield return ret;  <= loing_packet 를 콜한 콜러에게 send 해줌 , 또한 함수 선언에 리턴값으로 int 를 준다고 했으므로 리턴이 없거나 다른형을날리면 네트웍 시스템이 인지하여 경고처리가 가능

}

 로 표현이 됩니다.  마치 일반 어플리케이션 코딩하듯이 하면된다는거죠

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.