Kommunikation über Netty

Hallo zusammen,

ich mache grad meine ersten Schritte mit Netty und stehe vor einem Problem, für das mir noch keine gescheite Lösung einfällt.

Folgendes Szenario:
Es gibt eine Android App sowie einen Raspberry pi, die miteinander kommunizieren. Für die Kommunikation nutze ich auf beiden Seiten Netty.
Die Kommunikation läuft in der Regel immer so ab, dass die App eine Anfrage stellt und vom Raspberry eine Antwort bekommt.
Anfragen könnten sein: “Suche nach xy”, Antwort wäre dann eine Liste von Suchergebnissen. Oder: “Gib mir den aktuellen Status”, Antwort ist dann der Status (Was wird grad gespielt, Fortschritt, Lautstärke, …).

Der Weg Android App -> Raspberry war vergleichsweise einfach. Ich habe eine Klasse Command angelegt, die so ausschaut:

public class Command {

	private final String commandString;
	private final Map<String, Object> parameters;
	
	public Command(String commandString, Map<String, Object> parameters) {
		this.commandString = commandString;
		this.parameters = parameters;
	}
      
        // getter
}

commandString nimmt dann "search, “status”, etc. an. In parameters werden Suchparameter etc. gespeichert. Die Objekte dieser Klasse bekomme ich übertragen, die ChannelInitializer schauen so aus:
Server:

@Override
public void initChannel(SocketChannel ch) throws Exception {
	ChannelPipeline pipeline = ch.pipeline();
	pipeline.addLast("framer", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4, true));
								
	pipeline.addLast("string_decoder", new StringDecoder());
	pipeline.addLast("decoder", new JsonDecoder());
	pipeline.addLast("encoder", new JsonEncoder());
	pipeline.addLast("string_encode", new StringEncoder());

	pipeline.addLast("handler", new ServerHandler());
}

Anmerkungen:

  • Die Klasse ServerHandler erbt von ChannelInboundMessageHandlerAdapter und bekommt das deserialisierte Command übergeben, mit dem er dann direkt arbeiten kann.
  • Ich gehe absichtlich den Weg über Json, da auch noch eine iOS App angeschlossen werden soll. Ansonsten wäre vermutlich der Weg über Object De-/Encoder besser?

Client:

@Override
public void initChannel(SocketChannel ch) throws Exception {
	ChannelPipeline pipeline = ch.pipeline();
	pipeline.addLast("framer", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4, true));
	
	pipeline.addLast("string_decoder", new StringDecoder());
	pipeline.addLast("decoder", new JsonDecoder());
	pipeline.addLast("encoder", new JsonEncoder());
	pipeline.addLast("string_encode", new StringEncoder());

	pipeline.addLast("handler", new ClientHandler());
}

Wie gesagt, das Senden eines Command Objekts an den Server funktioniert einwandfrei. Meine Frage ist, wie die Antwort aussehen könnte.
Im Idealfall kann der Server direkt Objekte vom Typ Status, ArtistList, AlbumList, xxxList, etc. zurücksenden, die der Client dann weiterverarbeiten kann. Ich lege mich doch aber im ClientHandler auf genau einen Typ fest, ähnlich wie im ServerHandler (extends ChannelInboundMessageHandlerAdapter).
Kann ich der Pipeline mehrere Handler hinzufügen? Oder wie kann ich im ClientHandler Objekte unterschiedlichen Typs behandeln?

Soviel wollte ich eigentlich gar nicht schreiben, ich hoffe da steigt trotzdem jemand durch und kann mir ein paar Tipps geben, oder mir sagen ob man das irgendwie eleganter lösen kann.

nun , für app -> raspberry hast du ja auch nur genau eine klasse , für die antwort mehrere
ich würde in diesem fall eine ganz normale interface-struktur nehmen, alternativ natürlich abstract super oder gernerics
fakt ist jedenfalls : du bekommst einen “Response” in dem unterschiedlicher inhalt stecken kann
die aufgabe dem client mitzuteilen welchen inhalts-type dieser hat fällt dem protokoll zu

du könntest also alles erstmal als “Response” ansehen, und Response selbst hat dann die information welcher genauer sub-type enthalten ist

dürfte zumindest eleganter aussehen als ein riesiges if-else / switch mit instanceof

Soviel wollte ich eigentlich gar nicht schreiben, ich hoffe da steigt trotzdem jemand durch und kann mir ein paar Tipps geben, oder mir sagen ob man das irgendwie eleganter lösen kann.