WebSocketServerSockJsSession uses dedicated disconnect lock
Issue: SPR-14917
(cherry picked from commit a49809b)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -42,6 +42,7 @@ import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
|
|||||||
* A SockJS session for use with the WebSocket transport.
|
* A SockJS session for use with the WebSocket transport.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class WebSocketServerSockJsSession extends AbstractSockJsSession implements NativeWebSocketSession {
|
public class WebSocketServerSockJsSession extends AbstractSockJsSession implements NativeWebSocketSession {
|
||||||
@@ -54,6 +55,8 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
|
|
||||||
private final Object initSessionLock = new Object();
|
private final Object initSessionLock = new Object();
|
||||||
|
|
||||||
|
private final Object disconnectLock = new Object();
|
||||||
|
|
||||||
private volatile boolean disconnected;
|
private volatile boolean disconnected;
|
||||||
|
|
||||||
|
|
||||||
@@ -136,18 +139,14 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getNativeSession() {
|
public Object getNativeSession() {
|
||||||
if ((this.webSocketSession != null) && (this.webSocketSession instanceof NativeWebSocketSession)) {
|
return (this.webSocketSession instanceof NativeWebSocketSession ?
|
||||||
return ((NativeWebSocketSession) this.webSocketSession).getNativeSession();
|
((NativeWebSocketSession) this.webSocketSession).getNativeSession() : null);
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getNativeSession(Class<T> requiredType) {
|
public <T> T getNativeSession(Class<T> requiredType) {
|
||||||
if ((this.webSocketSession != null) && (this.webSocketSession instanceof NativeWebSocketSession)) {
|
return (this.webSocketSession instanceof NativeWebSocketSession ?
|
||||||
return ((NativeWebSocketSession) this.webSocketSession).getNativeSession(requiredType);
|
((NativeWebSocketSession) this.webSocketSession).getNativeSession(requiredType) : null);
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -166,7 +165,7 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
scheduleHeartbeat();
|
scheduleHeartbeat();
|
||||||
this.openFrameSent = true;
|
this.openFrameSent = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Throwable ex) {
|
||||||
tryCloseWithSockJsTransportError(ex, CloseStatus.SERVER_ERROR);
|
tryCloseWithSockJsTransportError(ex, CloseStatus.SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,10 +195,8 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessageInternal(String message) throws SockJsTransportFailureException {
|
public void sendMessageInternal(String message) throws SockJsTransportFailureException {
|
||||||
|
|
||||||
// Open frame not sent yet?
|
// Open frame not sent yet?
|
||||||
// If in the session initialization thread, then cache, otherwise wait.
|
// If in the session initialization thread, then cache, otherwise wait.
|
||||||
|
|
||||||
if (!this.openFrameSent) {
|
if (!this.openFrameSent) {
|
||||||
synchronized (this.initSessionLock) {
|
synchronized (this.initSessionLock) {
|
||||||
if (!this.openFrameSent) {
|
if (!this.openFrameSent) {
|
||||||
@@ -208,6 +205,7 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelHeartbeat();
|
cancelHeartbeat();
|
||||||
writeFrame(SockJsFrame.messageFrame(getMessageCodec(), message));
|
writeFrame(SockJsFrame.messageFrame(getMessageCodec(), message));
|
||||||
scheduleHeartbeat();
|
scheduleHeartbeat();
|
||||||
@@ -224,10 +222,12 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession implemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void disconnect(CloseStatus status) throws IOException {
|
protected void disconnect(CloseStatus status) throws IOException {
|
||||||
synchronized (this) {
|
if (isActive()) {
|
||||||
if (isActive()) {
|
synchronized (this.disconnectLock) {
|
||||||
this.disconnected = true;
|
if (isActive()) {
|
||||||
this.webSocketSession.close(status);
|
this.disconnected = true;
|
||||||
|
this.webSocketSession.close(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user