Page History
| Info |
|---|
멀티 플레이어 게임메시지 설계를 통해 AKKA-액터모델의 특징을 알아보겠습니다. 이 아티컬의 목표 : 여기서 진행되는 설계방식이 항상 권장되는 아키텍처는 아니며 웹소켓과 액터를 연결하여 심플한 멀티플레이어 웹게임서비스를 작성을 할수있는 메시지 중심의 최소한의 설계와 작동하는 최소한의 기능구현을 시도해보았습니다. |
웹소켓및 스프링 웹등은 메시지 기반의 멀티플레이어 게임을 만들기 위한 도구일뿐이며
...
AKKA의 액터를 이용한 버젼과, 전통적인 스레드를 사용하는 동일한 기능을 하는 두가지 버젼을 버전을 준비하였습니다.
스레드 버젼은 프로타잎용으로 먼저작성을 하였고, 이후 액터버젼으로 추가구현을 하였습니다.
두가지는 완전하게 같은 서버로직을 가지고 있으나 약간의 다른 메시지 패턴을 사용하였습니다.
그리고 이것은 불완전하기 때문에 지속적인 개선이 필요합니다.
스레드모델 VS 액터 모델
- 스레드 모델 : httpshttp://gitgithub.webnori.com/projectspsmon/SB2gameweb/repostree/gamewebmaster/browse/src/main/java/com/vgw/demo/gameweb/actorhttpthread
- 액터모델 : https://git.webnorigithub.com/projectspsmon/SB2gameweb/repostree/gamewebmaster/browse/src/main/java/com/vgw/demo/gameweb/thread/actor
- 전체 Code : https://github.com/psmon/gameweb
UseCase 설계
여기서 Actor는 처리가능한 서버로직입니다. 게임에 입장하기 전까지 UseCase를 통해 정리해보는것입니다.
메시지 흐름 중심이며 , AKKA의 액터모델로 구현하는것입니다.
액터 구성
UserCase 구상이 완료되면, 실제 메시지를 처리할 인스턴스를 작성하고 구조적으로 배치해야합니다.
AKKA System을 선택한 이유는, 액터를 잘 설계한다고하면, 코드의 큰 수정없이 클러스터로 확장이 용이합니다. - https://doc.akka.io/docs/akka/2.5/cluster-usage.html#a-simple-cluster-example
당장은 클러스터를 크게 분산처리를 신경쓰지 않고 진행을 하겠습니다.하여도, 이후 설계의 큰 변경없이 클러스터화가능합니다. - AKKA 액터의 장점
아직은 아무기능이 없으며 서버 기능을 하는 액터를 옹기종기 잘 모아 놓습니다.
응집력 있는 설계라도 표현되기도 합니다. ( 응집력 = 옹기종기 )
메시지 흐름 설계
그 다음 해야할일은 메시지 흐름을 구체화하는것입니다.
...
게임에 접속하고, 멀티플레이를 위한 테이블 공간에 참여시키는 메시지 시퀀스 다이어 그램
AKKA의 액터는 최종 프론트단(사용자) 에게 제공하는 통신 프로토콜이 아니며
웹소켓(WS)와 유연하게 연결하는 커뮤니케이션 레이어작성이 필요합니다.
메시지 처리기 구현
액터의 메시지는 오브젝트의 패턴매칭을 통해 분기처리가 가능합니다.
...
ActorPath를 통한 메시지 전송
액터의 중요한 속성중 하나인데하나이며, 액터는 그 어떤 액터와 상태 공유를 하지 않습니다. ( 할수없습니다.)
그래서 익숙한 도트접근을 통해 로컬에서 개발되었다고 해도 그어떤 값도 그 어떤 참조값을 도트로 얻어 낼수 없습니다.(메모리 공유를 원천 차단합니다.)
오로지 메시지를 통해서만 명령,응답을 기대할수 있습니다.
OOP VS ACTOR
| OOP | ACTOR |
|---|---|
Lobby a; a.getTable(1).getTableName(); | LobbyActor a; TableActor b; b.tell("some ask",a) |
OOP 객체중심의 설계는 네트워크로 확장이 어려울수 있습니다. - 원격지 오브젝트의 참조를 얻어낼수 있을까요? 답은 아니오입니다.
위 두차이를 이해하고, OOP를 적절하게 활용하여 액터에 내장을 시키면 OOP를 분산처리가능한 네트워크로 기능으로
확장할수 있습니다. ( 멀티스레드 프로그래밍과 네트워크 프로그래밍을 단순화하는 전략입니다.)로컬에서 구현이 복잡해지는 단점이 있으나, 리모트로 확장시 구현의 차이가 없어진다는 장점이 있습니다.
주소를 통한 Ask패턴사용
| Code Block | ||||
|---|---|---|---|---|
| ||||
private ActorRef findTableByID(int tableID) throws Exception {
String tableActorPath = "/user/lobby/table-"+tableID;
ActorSelection tableSelect = this.getContext().actorSelection(tableActorPath);
FiniteDuration duration = FiniteDuration.create(1, TimeUnit.SECONDS);
Future<ActorRef> fut = tableSelect.resolveOne(duration);
ActorRef tableActor = Await.result(fut, duration);
return tableActor;
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
ActorSelection lobbyActor = system.ActorSelection("user/lobby");
lobbyActor.tell("some message",null);
// 자식의 모든 요소 선택이 가능합니다.
ActorSelection tableAllActor = system.ActorSelection("user/lobby/table/*");
tableAllActor.tell("some message",null); |
ActorPath를 통한 여러 지점에으로의 우아한 메시지 전송을 다음 링크를 통해 살펴볼수 있습니다.
...
웹소켓을 액터에 연결하기
| Include Page | ||||
|---|---|---|---|---|
|
유닛테스트
| Include Page | ||||
|---|---|---|---|---|
|
샘플데모
기타 유용한링크
- https://getakka.net/articles/intro/what-are-actors.html
- https://doc.akka.io/docs/akka/2.5/general/addressing.html - Actor Path
- https://www.baeldung.com/akka-with-spring
기타 참고자료
또한 메시지 처리에서 Thread와 Actor를 비교해보는것은 , 메시징 처리를 위한 좋은 학습자료가 될것입니다.
- https://getakka.net/articles/intro/what-are-actors.html
- http://alexminnaar.com/introduction-to-the-multithreading-problem-and-the-akka-actor-solution.html


