Coda messaggi tra server e motore

2

Ho intenzione di utilizzare una coda messaggi per le comunicazioni tra un motore di gioco e un server di gioco. Questo dovrebbe permettermi di scrivere entrambi senza dipendenze dirette tra loro.

L'esempio che userò in questa domanda è un DisconnectMessage . Un server può inviare un DisconnectMessage al motore se, ad esempio, il client ha superato il valore di timeout e non ha risposto a una richiesta ping. Il motore può anche inviare DisconnectMessage al server se, ad esempio, un operatore del server emette un comando kick per un giocatore. In entrambi i casi, il giocatore viene salvato nel repository del giocatore del gioco.

Quindi quello che ho al momento è un server, un motore di gioco e due code di messaggi (uno per l'entrata, uno per l'uscita).

Per ora, quello che mi piacerebbe avere è un'istanza di un gestore di messaggi sicuro per ogni tipo di messaggio. È qui che il problema è per me, poiché non riesco a ottenere un gestore specifico per un messaggio generico.

Il codice che ho è qualcosa del tipo:

public interface GameMessage {

}

public interface GameMessageHandler<T extends GameMessage> {

    public void handle(T message);
}

public class DisconnectMessage implements GameMessage {
    // ...
}

public class DisconnectMessageHandler implements GameMessageHandler<DisconnectMessage> {

    @Override
    public void handle(DisconnectMessage message) {
        // ... something something
    }
}

public class GameEngine implements Runnable {

    public GameEngine(Queue<GameMessage> in, Queue<GameMessage> out) {
        // ...
    }

    @Override
    public void run() {
        if (!in.empty()) {
            GameMessage message = in.poll();

            handle(message);
        }
    }
}

Il metodo corrente che ho (che non funziona) è il seguente

// in GameEngine
public <T extends GameMessage> void handle(T message) {
    GameMessageHandler<T> handler = getHandler(message.getClass());

    handler.handle(message);
}

public <M extends Message, H extends GameMessageHandler<M>> H getHandler(Class<M> messageClass) {
    // get handler somehow from a dictionary
}

Tuttavia, il sistema di tipi di Java non mi consente di ottenere ciò in questo modo.

C'è un modo per ottenere un gestore di messaggi concreto dalla classe di interfaccia di base?

O forse una domanda diversa che potrebbe cambiare la risposta; esiste un modo diverso / migliore rispetto all'utilizzo di una coda messaggi per impedire una dipendenza circolare?

    
posta Zymus 22.09.2016 - 06:15
fonte

1 risposta

1

Usare le code è una buona idea, ma non sono un fan dell'uso della serializzazione Java per passare gli oggetti messaggio, o di utilizzare classi java per rappresentare vari tipi di messaggio. L'intero processo di serializzazione è troppo opaco, inefficiente, e dispendioso dell'ampiezza di banda. È anche fragile, nel senso che piccole differenze tra gerarchie di classe client e server possono causare il comunicazione per rompere, e non c'è speranza di avere clienti che non sono basati sulle stesse classi Java.

Definirei la struttura del messaggio come un flusso di testo che può essere analizzato, e implementare le classi java per stamparle / analizzarle. La quantità che questi messaggi sono implementati da classi java a te.

Ti ringrazierai quotidianamente per aver reso il tuo flusso di comunicazione di base qualcosa che dovrebbe essere umanamente comprensibile. E non dimenticare per fare affidamento sul sequenziamento end-to-end, sui checksum e sugli hash l'integrità delle tue comunicazioni. Gli errori di rete non sono gli unici cosa ti stai nascondendo - ci sono anche bug in altre parti del processo e la prospettiva che gli hacker interferiscano con le tue comunicazioni.

    
risposta data 22.09.2016 - 07:25
fonte

Leggi altre domande sui tag