Netty synchroner Client mit asynchronen Anrufern

Ich erstelle einen Server, der Befehle aus zahlreichen Quellen wie JMS, SNMP, HTTP usw. verwendet. Diese sind alle asynchron und funktionieren einwandfrei. Der Server unterhält eine einzelne Verbindung zu einer einzelnen Legacy-Hardware, die über eine Anforderungs- / Antwortarchitektur mit einem benutzerdefinierten TCP-Protokoll verfügt. Im Idealfall möchte ich einen einzelnen Befehl wie diese Methode blockieren Typ

public Response issueCommandToLegacyHardware(Command command)

oder diese asynchrone Typmethode

public Future<Response> issueCommandToLegacyHardware(Command command)

Ich bin relativ neu in der Netty- und asynchronen Programmierung und lerne sie im Grunde genommen im Laufe der Zeit. Mein aktueller Gedanke ist, dass meinLegacyHardwareClient Klasse wird @ habpublic synchronized issueCommandToLegacyHardware(Command command), schreibt in den Client-Kanal an die alte Hardware, danntake() von einemSynchronousQueue<Response> was wird blockieren. Der ChannelInboundHandler in der Pipeline wirdoffer() a Response zumSynchronousQueue>Response> was das @ erlauben witake(), um die Sperrung aufzuheben und die Daten zu empfangen.

Ist das zu verworren? Gibt es Beispiele für synchrone Netty-Client-Implementierungen, die ich mir ansehen kann? Gibt es Best Practices für Netty? Ich könnte natürlich nur Standard-Java-Sockets verwenden, aber die Leistung von Netty zum Parsen von benutzerdefinierten Protokollen und die einfache Wartung sind viel zu groß, um darauf zu verzichte

UPDATE: In Bezug auf die Implementierung habe ich ArrayBlockingQueue <> () und put () und remove () anstelle von offer () und remove () verwendet. Weil ich sicherstellen wollte, dass nachfolgende Anforderungen an die Legacy-Hardware nur gesendet wurden, wenn aktive Anforderungen beantwortet wurden, da das Verhalten der Legacy-Hardware ansonsten nicht mit Sicherheit bekannt ist.

Der Grund, warum offer () und remove () für mich nicht funktionierten, war, dass der offer () -Befehl nichts weitergab, wenn es keine aktiv blockierende take () -Anforderung gab. Die Umkehrung ist wahr, dass remove () nichts zurückgeben würde, es sei denn, es gab einen blockierenden put () -Aufruf zum Einfügen von Daten. Ich konnte put () / remove () nicht verwenden, da die Anweisung remove () niemals erreicht werden würde, da keine Anforderung in den Kanal geschrieben wurde, um das Ereignis auszulösen, von dem aus remove () aufgerufen wird. Ich konnte offer () / take () nicht verwenden, da die offer () - Anweisung false zurückgeben würde, da der take () - Aufruf noch nicht ausgeführt wurde. Mit dem ArrayBlockingQueue <> () mit einer Kapazität von 1 wurde sichergestellt, dass nur ein Befehl gleichzeitig ausgeführt werden konnte. Alle anderen Befehle wurden blockiert, bis genügend Platz zum Einfügen vorhanden war. Bei einer Kapazität von 1 bedeutete dies, dass sie leer sein musste. Das Leeren der Warteschlange wurde durchgeführt, nachdem eine Antwort von der alten Hardware empfangen wurde. Dies stellte ein gutes synchrones Verhalten gegenüber der Legacy-Hardware sicher, stellte jedoch eine asynchrone API für die Benutzer der Legacy-Hardware bereit, für die es viele gibt.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage