Pokoje w grze multiplayer

0

Witam. Jestem w trakcie tworzenia bardzo prostej gry multiplayer (bez logowania), gdzie można stworzyć prywatny pokój i do niego dołączać, żeby zagrać albo dołączyć do jakiegoś publicznego. Korzystam ze spring websocket razem ze stompem. Chciałbym zrobić to tak, że wszelkie polecenia dot. pokoi (tworzenie, dołączanie, opuszczanie) idą przez zwykłe zapytania http POST albo PUT a reszta przez websocket. Nie mam szczerze pojęcia jak się za to zabrać. Chciałbym, żeby np. wyglądało to tak

  1. User1 wchodzi na aplikacje i łączy się z serwerem ws
  2. User1 tworzy pokój przez http POST i dostaje informacje zwrotną o numerze pokoju
  3. User2 wchodzi do pokoju przez http PUT
  4. Serwer websocket przesyła do każdego użytkownika w pokoju informację o tym, że user2 dołączył i zwraca jego dane

Dodatkowo na razie zrobiłem tak, że gdy ktoś na wejściu łączy się z serwerem ws to w systemie jest tworzony nowy użytkownik i jest on przypisywany do tej sesji za pomocą metody determineUser z AbstractHandshakeHandlera. Tylko, że problem jest taki, że np. podczas wykonywania zwykłego zapytania http POST nie mam oczywiście dostępu do obiektu Principal. Czyli musiałbym np. zwracać to id do klienta zaraz po wykonaniu połączeniu z serwerem ws i wtedy przesyłać je z powrotem na serwer np. przy tworzeniu pokoju. Tylko czy to wszystko ma sens? Może zrobić to całkowicie inaczej? Albo w ogóle nie wykonywać tych rzeczy dot. pokoi przez http tylko po prostu przez websocket? Jak będzie lepiej?


public class CustomHandshakeHandler extends DefaultHandshakeHandler {

    private final RoomDomainFacade roomDomainFacade;

    @Override
    protected Principal determineUser(
            ServerHttpRequest request,
            WebSocketHandler wsHandler,
            Map<String, Object> attributes
    ) {
        String createdPlayerId = roomDomainFacade.createPlayer();
        return new WebsocketPrincipal(createdPlayerId);
    }

3
Jakub Noxay napisał(a):
  1. User1 tworzy pokój przez http POST i dostaje informacje zwrotną o numerze pokoju
  2. User2 wchodzi do pokoju przez http PUT

Nic z tego nie rozumiem, ale te dwa zdania tak.
Z lekkim dreszczem, ale to może kwestia pogody ?

Mocno to pachnie, jakbyś w jednej myśli chciał określić rzeczy wysokopizomowe (logiczne / biznesowe) i niskopoziomowe (bebechy ServerHttpRequest ) - nie może z tego wyjść nic dobrego

2

Za wcześnie wchodzisz w abstrakcję.
Najpierw wyobraź sobie jak to wygląda w rzeczywistości np na przykładzie karaoke:
Zwracasz się do kelnera z jednym z dwóch pytań:

  1. Zamawiam pokój (ewentualnie na nazwisko lub o nazwie), kelner (po sprawdzeniu listy wolnych) odpowiada: - zapraszam do pokoju X
  2. Chcę dołączyć do pokoju X (lub na nazwisko lub o nazwie), kelner odpowiada: - zapraszam do pokoju X
    Zauważ że jedyną różnicą jest sposób określenia numeru pokoju.
2

Można do tego podejść na dwa sposoby. Pierwszym jest ten który wybrałeś: WS tylko w roli dystrybutora informacji live o zmianie stanu w grze w kierunku S->K. Żądania K->S modyfikujące stan gry, w tym pobieranie pełnych danych "na żądanie" REST-owo przez HTTP. Masz wtedy na utrzymaniu dwie warstwy komunikacji (a więc i dwa sposoby na autoryzację, dwa sposoby wymiany informacji z klientem) i musisz zawsze pilnować by każda z nich miała swoje niezależne kompetencje, bo łatwo zrobić bałagan. To podejście ma tę zaletę, że aby skomunikować się z aplikacją wystarczy wysłać jej request HTTP co z zasady jest najprostszym rozwiązaniem; jeśli przewidujesz klienta który nie będzie wymagał aktualizacji live (np. bot-mikroserwis wykonujący jakieś pomocnicze akcje na serwerze gry) nie będziesz musiał martwić się o utrzymywanie połączenia WS.

Innym podejściem jest zastosowanie dwukierunkowej komunikacji K<->S po WS. Zaletami jest tu brak konieczności utrzymania REST API i mniejszy ruch sieciowy zarówno po stronie klienta i serwera; pojedyncze zestawienie połączenia i jazda.

Generalnie jest to kluczowa decyzja i warto na tym etapie spróbować przewidzieć czego będziesz potrzebował w przyszłości.

1 użytkowników online, w tym zalogowanych: 0, gości: 1