문제

나는 디자인하는 게임 서버 스크립팅 기능이다.일반적인 디자인은 다음과 같습니다.

Client connects to Server,
Server initializes Client,
Server sends Client to EventManager (separate thread, uses libevent),
EventManager receives receive Event from Client socket,
Client manages what it received via callbacks.

지금 마지막 부분은 무엇이 가장 까다로운 나를 위해 지금입니다.

현재 나의 디자인은 나를 위해 클래스를 상속받 Client 을 만들 콜백을 보시려 받는 이벤트입니다.이러한 콜백을 관리 목록에서 수신 버퍼를 통해 간 분석 프로세스의 각 시간 뭔가를 받았습니다.면 버퍼가 유효한 경우,콜백이라는 곳에 따라 행동에 무엇이 있습니다.한가지 유의할 사항은 콜백을 갈 수 있습니다 스크립트 엔진 시점에서 아무것은 무슨 일이 일어날 수 있습니다.

각 시간을 콜백이 완료되면 현재 수신 버퍼를 다시 설정해야 등입니다.콜백을 현재가 없는 기능을 반환하는 값이므로 언급하기 전에,어떤 일이 일어날 수 있습니다.

무슨 일이 어딘가에 때 콜백에서 뭔가를 말이->disconnect(),고 싶은 즉시 연결 끊기 Client, 에서 제거 EventManager,그리고 마지막으로 그것을 제거에서 Server, 는 곳에,그것은 또한 받아야 마지막으로 파괴되고 메모리.그러나,여전히 몇 가지 코드를 실행한 후에 콜백을 끝에서 클라이언트,따라서 할 수 없습니다.

나는 무엇을 해야에 변화를 디자인?해야 하는 일부를 타임 이벤트 Server 를 확인하는 Clients 무료 파괴?는 추가로 만들 오버헤드가 필요 없어요?그것은 여전히 후에 좋은 콜백을 완료하기 전 최소한의 실행 코드를 스택에서(return -1; 다)또는지?

나는 아무 생각이 무엇을 할,하지만 내가 열려 전체 설계 진짜 장르에 치.

미리 감사드립니다.

도움이 되었습니까?

해결책

참조 카운트 포인터와 같은 참조 카운트를 사용할 수 있습니다 boost::shared_ptr<> 메모리 관리를 단순화합니다. 관리자의 클라이언트 목록이 사용하는 경우 shared_ptrs와 콜백을 호출하는 코드는 로컬 사본을 만듭니다. shared_ptr 콜백이 호출되고, 개체는 관리자에서 제거 될 때까지 살아 남을 것입니다. 그리고 콜백 함수가 완료되었습니다.

class EventManager {
  std::vector< boost::shared_ptr<Client> > clients;

  void handle_event(Event &event) {
    // local |handler| pointer keeps object alive until end of function, even
    // if it removes itselfe from |clients|
    boost::shared_ptr<Client> handler = ...;
    handler->process(event);
  }
};

class Client {
  void process(Event &event) {
    manager->disconnect(this);
    // the caller still holds a reference, so the object lives on
  }
}

그만큼 Client 마지막으로 객체가 자동으로 삭제됩니다 shared_ptr 그것은 범위를 벗어나지 만 이전은 아닙니다. 그래서 로컬 사본을 작성합니다 shared_ptr 함수 호출 전에 객체가 예기치 않게 삭제되지 않도록합니다.

다른 팁

처음부터 끝까지 특정 메시지 흐름 (1 클라이언트에서)을 추적하는 "세션"과 같은 객체를 고려해야합니다. 이 객체는 또한 현재 상태를 처리해야합니다. 주로 버퍼 및 처리. 콜백을 트리거하는 각 이벤트는 해당 세션 상태를 업데이트해야합니다. Libevent는 예정된 이벤트의 결과와 같은 성공, 실패, 시간 초과를 제공 할 수 있습니다. 이 유형 각각은 논리에 반영되어야합니다. 일반적으로 이벤트 작업을 수행 할 때 처리 로직이 상태와의 오토 마톤으로 간주하십시오.

http://en.wikipedia.org/wiki/reactor_pattern 작업에 좋은 자원이 될 수 있습니다.

자 클라이언트::disconnect()함수는 send 이벤트 매니저(또는 서버는)클래스입니다.이 할 필요가 있다는 것을 의미한 일종의 이벤트 처리에서 매니저(또는 서버),이벤트에 대한 루프 인스턴스입니다.

나의 일반적인 아이디어는 클라이언트::disconnect()연결이 끊어지지 않습 즉시 클라이언트,하지만 후에 콜백을 완성된 실행됩니다.대신,그것은 그냥 게시물에 이벤트 매니저(또는 서버는)클래스입니다.

한 주장할 수 있습니다 클라이언트::disconnect()메소드가 잘못된 클래스입니다.어쩌면 그것이 있어야 Server::disconnect(클라이언트*c).는 것에 더 많은 온라인으로 아이디어는 서버에'소유하는'클라이언트와 서버는 연결을 끊은 클라이언트(및 그 후 업데이트 내부에 부기).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top