WebSocket, async senden führen kann, blockiert senden sobald die queue gefüllt
Habe ich ziemlich einfachen Jetty-basierten websockets-server, verantwortlich für das streaming von kleinen binären Nachrichten: verbinden von clients.
Um keine Sperrung auf server-Seite war ich mit sendBytesByFuture Methode.
Nachdem die steigende Belastung von 2 Kunden um 20, hören Sie auf, erhalten Sie keine Daten. Während der Fehlersuche habe ich beschlossen, wechseln auf die synchrone send-Methode und endlich mögliche Ursache:
java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130)
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendBytes(WebSocketRemoteEndpoint.java:244)
Kunden nicht tun, werden keine Berechnungen nach Erhalt der Daten, so dass Sie möglicherweise nicht sein können, langsam Zugänge.
Also ich Frage mich, was kann ich tun, um dieses problem zu lösen?
(mit Jetty 9.2.3)
- Ist dies mithilfe von JSR-356 (javax.websocket) oder native websocket-api?
- Native, ausgeliefert mit Steg selbst
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die Fehlermeldung Auftritt, von einem synchronen senden, dann hast du mehrere threads, die versuchen, Nachrichten zu senden, auf dem gleichen
RemoteEndpoint
- etwas, das nicht erlaubt ist pro das Protokoll. Nur 1 Nachricht gesendet werden kann. (Es gibt im wesentlichen keine Warteschlange für synchrone sendet)Wenn die Fehlermeldung Auftritt, von einem asynchronen senden, dann bedeutet das, dass Sie Nachrichten, die sitzen in einer Warteschlange gesendet werden, doch Sie sind immer noch versucht, mehr zu schreiben, async-Meldungen.
Versuchen Sie, nicht zu mischen, synchron-und asynchron-in der gleichen Zeit (es wäre sehr einfach, versehentlich ausgegeben haben, die zu einer ungültigen Protokoll-stream)
Mit Java-Futures:
Werden Sie wollen, verwenden Sie die
Zukunft
Objekte, die auf die Rückkehr dersendBytesByFuture()
undsendStringByFuture()
Methoden, um zu überprüfen, dass die Nachricht tatsächlich gesendet wurde oder nicht (könnte ein Fehler gewesen), und wenn genug beginnen Schlange ungesendeten Sie wieder ab auf das senden von Nachrichten mehr, bis die remote-Endpunkt aufholen können.Standard
Future
Verhalten und Techniken anzuwenden.Mit Steg-Rückrufe:
Gibt es auch die
WriteCallback
Verhalten verfügbar in densendBytes(ByteBuffer,WriteCallback)
undsendString(String,WriteCallback)
Methoden, rufen Sie Ihren eigenen code auf Erfolg/Fehler, auf die Sie setzen können, etwas Logik, um was Sie senden (limit, senden Sie es langsamer, Warteschlange es, Sie zu filtern, löschen Sie einige Nachrichten, Priorisierung von Nachrichten, etc. was auch immer Sie brauchen)Mit Blockierung:
Oder können Sie einfach blockieren sendet, um nie zu viele Nachrichten in eine Warteschlange.