우선 메시지 처리를 하기 위한 서비스를 생성합니다.
// 패킷 처리 유저 생성
var myService = builder.createGameService("MyChatService");
myService.user("Chat", ChatUser::new, config -> {
// 여기에 핸들러를 추가합니다
});
이렇게 생성한 CharUser에 원하는 메시지와 핸들러를 연결합니다.
var myService = builder.createGameService("MyChatService");
myService.user("Chat", ChatUser::new, config -> {
// 처리하고 싶은 메시지와 핸들러를 매핑
config.protoBufferHandler(EchoSend.class, new _MyEchoHandler());
});
메세지는 설정 시 전달받은 config를 통해 핸들러를 추가할 수 있습니다. protoBufferHandler 핸들러의 첫 번째 인자는 설정하려는 ProtoBuffer의 클래스이고 두 번째 인자는 핸들러입니다.
이제 해당 메시지 핸들러를 직접 구현합니다. 이때, GameAnvil은 엔진 내부는 물론이고 모든 샘플 코드에서 메시지 핸들러에 대해 _로 시작하는 네이밍을 사용합니다. 앞으로 등장하는 모든 예제 코드에서도 _로 시작하는 클래스는 모두 메시지 핸들러입니다. 가장 기본적인 형태의 메시지 핸들러는 아래와 같습니다. CONTEXT_CLASS는 해당 메시지의 흐름을 나타내는 클래스를 의미합니다. Context 클래스에서 대상 객체 획득, 메시지의 응답 등을 할 수 있습니다.
public class _MyEchoHandler implements IMessageHandler<CONTEXT_CLASS, EchoSend> {
@Override
public void execute(CONTEXT_CLASS ctx, EchoSend request) {
System.out.println("Receive EchoSend Message!");
}
}
예를 들어, 패킷 수신자가 GameUser라면 그 메시지 핸들러는 아래와 같습니다.
public class _MyEchoHandler implements IMessageHandler<IUserDispatchContext, EchoSend> {
@Override
public void execute(IUserDispatchContext ctx, EchoSend request) {
System.out.println("Receive EchoSend Message!");
}
}
간단한 클래스라면 람다 혹은 메서드를 직접 전달하는 방법도 좋습니다. 예를 들어 메서드로 전달 시 코드는 아래와 같습니다.
final var myService = builder.createGameService("MyChatService");
myService.user("Chat", ChatUser::new, config -> {
config.protoBufferHandler(EchoSend.class, MyClass::runEchoSend);
});
private static void runEchoSend(IUserDispatchContext ctx, EchoSend sendMsg) {
System.out.println("Receive EchoSend Message!");
}
패킷 디스패처는 두 가지가 존재합니다. 하나는 앞서 살펴본 일반적인 패킷 디스패처이고 다른 하나는 RESTful 요청을 처리하기 위한 디스패처입니다. 전체적인 사용법은 두 가지가 거의 동일합니다. 단, 이러한 RESTful 메시지 처리는 오직 SupportNode만 지원합니다.
다음의 예제 코드는 RESTful 요청을 처리하기 위해 이전과 다른 RestPacketDispatcher를 생성하고 있습니다. 또한 메시지 클래스가 아닌 URL 형태의 API를 핸들러에 연결하고 있습니다.
final var spt = builder.createSupportService("MySupport");
spt.supportNode(ConsoleTestSupportNode::new, config -> {
config.httpHandler("/hello", RestObject.GET, new _RestAuthReq());
});
예제 코드와 같이 RestMessageDispatcher 사용하여 사용자가 원하는 RESTful API와 메시지 핸들러를 연결하고 있습니다.
RESTful 메시지 핸들러는 Packet 대신 RestObject가 인자로 전달되는 차이점 외에는 동일한 모습입니다.
public class _RestAuthReq implements IRestMessageHandler<WebSupportNode> {
private static final Logger logger = getLogger(_RestAuthReq.class);
@Override
public void execute(WebSupportNode node, RestObject restObject) throws SuspendExecution {
...
}
}