[Java] Don't call onClose when WebSocket connection is not open (#28004)
This commit is contained in:
parent
4b46b26896
commit
4731c87476
|
|
@ -30,7 +30,7 @@ class OkHttpWebSocketWrapper extends WebSocketWrapper {
|
||||||
private WebSocketOnClosedCallback onClose;
|
private WebSocketOnClosedCallback onClose;
|
||||||
private CompletableSubject startSubject = CompletableSubject.create();
|
private CompletableSubject startSubject = CompletableSubject.create();
|
||||||
private CompletableSubject closeSubject = CompletableSubject.create();
|
private CompletableSubject closeSubject = CompletableSubject.create();
|
||||||
private final ReentrantLock closeLock = new ReentrantLock();
|
private final ReentrantLock stateLock = new ReentrantLock();
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(OkHttpWebSocketWrapper.class);
|
private final Logger logger = LoggerFactory.getLogger(OkHttpWebSocketWrapper.class);
|
||||||
|
|
||||||
|
|
@ -82,7 +82,12 @@ class OkHttpWebSocketWrapper extends WebSocketWrapper {
|
||||||
private class SignalRWebSocketListener extends WebSocketListener {
|
private class SignalRWebSocketListener extends WebSocketListener {
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(WebSocket webSocket, Response response) {
|
public void onOpen(WebSocket webSocket, Response response) {
|
||||||
|
stateLock.lock();
|
||||||
|
try {
|
||||||
startSubject.onComplete();
|
startSubject.onComplete();
|
||||||
|
} finally {
|
||||||
|
stateLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -97,39 +102,64 @@ class OkHttpWebSocketWrapper extends WebSocketWrapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClosing(WebSocket webSocket, int code, String reason) {
|
public void onClosing(WebSocket webSocket, int code, String reason) {
|
||||||
onClose.invoke(code, reason);
|
boolean isOpen = false;
|
||||||
|
stateLock.lock();
|
||||||
try {
|
try {
|
||||||
closeLock.lock();
|
isOpen = startSubject.hasComplete();
|
||||||
|
} finally {
|
||||||
|
stateLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("WebSocket closing with status code '{}' and reason '{}'.", code, reason);
|
||||||
|
|
||||||
|
// Only call onClose if connection is open
|
||||||
|
if (isOpen) {
|
||||||
|
onClose.invoke(code, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
stateLock.lock();
|
||||||
closeSubject.onComplete();
|
closeSubject.onComplete();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
closeLock.unlock();
|
stateLock.unlock();
|
||||||
}
|
}
|
||||||
checkStartFailure();
|
checkStartFailure(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
||||||
logger.error("WebSocket closed from an error: {}.", t.getMessage());
|
logger.error("WebSocket closed from an error.", t);
|
||||||
|
|
||||||
|
boolean isOpen = false;
|
||||||
try {
|
try {
|
||||||
closeLock.lock();
|
stateLock.lock();
|
||||||
if (!closeSubject.hasComplete()) {
|
if (!closeSubject.hasComplete()) {
|
||||||
closeSubject.onError(new RuntimeException(t));
|
closeSubject.onError(new RuntimeException(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isOpen = startSubject.hasComplete();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
closeLock.unlock();
|
stateLock.unlock();
|
||||||
}
|
}
|
||||||
|
// Only call onClose if connection is open
|
||||||
|
if (isOpen) {
|
||||||
onClose.invoke(null, t.getMessage());
|
onClose.invoke(null, t.getMessage());
|
||||||
checkStartFailure();
|
}
|
||||||
|
checkStartFailure(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkStartFailure() {
|
private void checkStartFailure(Throwable t) {
|
||||||
|
stateLock.lock();
|
||||||
|
try {
|
||||||
// If the start task hasn't completed yet, then we need to complete it
|
// If the start task hasn't completed yet, then we need to complete it
|
||||||
// exceptionally.
|
// exceptionally.
|
||||||
if (!startSubject.hasComplete()) {
|
if (!startSubject.hasComplete()) {
|
||||||
startSubject.onError(new RuntimeException("There was an error starting the WebSocket transport."));
|
startSubject.onError(new RuntimeException("There was an error starting the WebSocket transport.", t));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
stateLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,6 @@ class WebSocketTransport implements Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onClose(Integer code, String reason) {
|
void onClose(Integer code, String reason) {
|
||||||
logger.info("WebSocket connection stopping with " +
|
|
||||||
"code {} and reason '{}'.", code, reason);
|
|
||||||
if (code == null || code != 1000) {
|
if (code == null || code != 1000) {
|
||||||
onClose.invoke(reason);
|
onClose.invoke(reason);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue