会话关闭时使用 Spring WebSocketConnectionManager 的正确方法是什么
What is the proper way to use Spring WebSocketConnectionManager when sessions closes
我使用 Spring 的 WebSocketConnectionManager to work with WebSockets. Sometimes the connection closes and I have to reconnect. But I didn't find any proper solution to do that. Can I use WebSocketConnectionManager for restore (reconnect to) session? In the sources I see,该连接通过以下代码建立:
@Override
protected void openConnection() {
if (logger.isInfoEnabled()) {
logger.info("Connecting to WebSocket at " + getUri());
}
ListenableFuture<WebSocketSession> future =
this.client.doHandshake(this.webSocketHandler, this.headers, getUri());
future.addCallback(new ListenableFutureCallback<WebSocketSession>() {
@Override
public void onSuccess(@Nullable WebSocketSession result) {
webSocketSession = result;
logger.info("Successfully connected");
}
@Override
public void onFailure(Throwable ex) {
logger.error("Failed to connect", ex);
}
});
}
当我的 spring 引导应用程序启动时,我正在使用此管理器:
WebSocketConnectionManager connectionManager = new WebSocketConnectionManager(
new StandardWebSocketClient(), webSocketHandler, "wss://localhost:8080/ws/");
connectionManager.start();
但是当连接关闭时我必须做什么?我试图从 openConnection() 复制一段代码,并使用它直接在 webSocketHandler 中更新会话,并且它有效。但它看起来像是肮脏的解决方法。
有人知道如何正确操作吗?谢谢。
我认为你不需要直接在webSocketHandler
中复制openConnection
函数。您应该能够重新使用 openConnection
函数并从 WebSocketConnectionManager.
内部捕获 afterConnectionClose
事件
我认为您的方向是正确的。不幸的是,我不认为这是一个肮脏的解决方法,因为 WebSocketConnectionManager 内部不存在任何东西来处理 WebSocket "on close" 事件。
在 WebSocketConnectionManager 的文档中,我看到了以下摘录:
A WebSocket connection manager that is given a URI, a WebSocketClient,
and a WebSocketHandler, connects to a WebSocket server through
ConnectionManagerSupport.start() and ConnectionManagerSupport.stop()
methods. If ConnectionManagerSupport.setAutoStartup(boolean) is set to
true this will be done automatically when the Spring
ApplicationContext is refreshed.
JavaScript 的 WebSocket onClose
对于 Spring 的 WebSocketConnectionManager 的等价物似乎是 afterConnectionClosed
,您可以在 [=24= 的文档中找到它].事实上,afterConnectionClosed
上的文档说:
afterConnectionClosed
- Invoked after the WebSocket connection has been closed by either side,
or after a transport error has occurred. Although the session may
technically still be open, depending on the underlying implementation,
sending messages at this point is discouraged and most likely will not
succeed.
因此,我认为您的 Spring 代码需要包含类似于以下伪代码的内容:
afterConnectionClosed(WebSocketSession result, CloseStatus closeStatus) {
// Spring code here to delay retry for re-connecting to WebSocket.
openConnection()
};
JavaScript 等价物是:
ws.onclose = function(){
// Try to reconnect in 5 seconds
setTimeout(function(){start(websocketServerLocation)}, 5000);
};
希望有 Spring 经验的人可以过来编辑一下 post 并指出我正确的地方和错误的地方。我不使用 Spring 但我有一些 WebSocket 经验。在 JavaScript 中,我使用 reconnecting-websocket so my gut tells me you'll essentially need to implement this functionality in Spring if it does not already exist. Or as this answer 建议 JavaScript,您需要从 WebSocket 捕获 onClose
事件并重新连接。
有趣的是,Spring repo 中有一些名为 onClose
的方法,所以也许这个问题需要重新审视。
在我的一个项目中,我遇到了类似的情况。
因此,我求助于使用 start() 和 stop() 方法访问 WebSocketManager 作为连接管理器中的 bean class。
我之前为 websocketserver and websocketclient 创建了一个示例项目。刚刚为其添加了重新连接功能。
此外,我并没有在每次连接关闭时都重新连接。仅在close status 1006(异常关闭)、1011(内部错误)和1012(服务重启)时。
工程可以直接下载运行。
我使用 Spring 的 WebSocketConnectionManager to work with WebSockets. Sometimes the connection closes and I have to reconnect. But I didn't find any proper solution to do that. Can I use WebSocketConnectionManager for restore (reconnect to) session? In the sources I see,该连接通过以下代码建立:
@Override
protected void openConnection() {
if (logger.isInfoEnabled()) {
logger.info("Connecting to WebSocket at " + getUri());
}
ListenableFuture<WebSocketSession> future =
this.client.doHandshake(this.webSocketHandler, this.headers, getUri());
future.addCallback(new ListenableFutureCallback<WebSocketSession>() {
@Override
public void onSuccess(@Nullable WebSocketSession result) {
webSocketSession = result;
logger.info("Successfully connected");
}
@Override
public void onFailure(Throwable ex) {
logger.error("Failed to connect", ex);
}
});
}
当我的 spring 引导应用程序启动时,我正在使用此管理器:
WebSocketConnectionManager connectionManager = new WebSocketConnectionManager(
new StandardWebSocketClient(), webSocketHandler, "wss://localhost:8080/ws/");
connectionManager.start();
但是当连接关闭时我必须做什么?我试图从 openConnection() 复制一段代码,并使用它直接在 webSocketHandler 中更新会话,并且它有效。但它看起来像是肮脏的解决方法。
有人知道如何正确操作吗?谢谢。
我认为你不需要直接在webSocketHandler
中复制openConnection
函数。您应该能够重新使用 openConnection
函数并从 WebSocketConnectionManager.
afterConnectionClose
事件
我认为您的方向是正确的。不幸的是,我不认为这是一个肮脏的解决方法,因为 WebSocketConnectionManager 内部不存在任何东西来处理 WebSocket "on close" 事件。
在 WebSocketConnectionManager 的文档中,我看到了以下摘录:
A WebSocket connection manager that is given a URI, a WebSocketClient, and a WebSocketHandler, connects to a WebSocket server through ConnectionManagerSupport.start() and ConnectionManagerSupport.stop() methods. If ConnectionManagerSupport.setAutoStartup(boolean) is set to true this will be done automatically when the Spring ApplicationContext is refreshed.
JavaScript 的 WebSocket onClose
对于 Spring 的 WebSocketConnectionManager 的等价物似乎是 afterConnectionClosed
,您可以在 [=24= 的文档中找到它].事实上,afterConnectionClosed
上的文档说:
afterConnectionClosed
- Invoked after the WebSocket connection has been closed by either side, or after a transport error has occurred. Although the session may technically still be open, depending on the underlying implementation, sending messages at this point is discouraged and most likely will not succeed.
因此,我认为您的 Spring 代码需要包含类似于以下伪代码的内容:
afterConnectionClosed(WebSocketSession result, CloseStatus closeStatus) {
// Spring code here to delay retry for re-connecting to WebSocket.
openConnection()
};
JavaScript 等价物是:
ws.onclose = function(){
// Try to reconnect in 5 seconds
setTimeout(function(){start(websocketServerLocation)}, 5000);
};
希望有 Spring 经验的人可以过来编辑一下 post 并指出我正确的地方和错误的地方。我不使用 Spring 但我有一些 WebSocket 经验。在 JavaScript 中,我使用 reconnecting-websocket so my gut tells me you'll essentially need to implement this functionality in Spring if it does not already exist. Or as this answer 建议 JavaScript,您需要从 WebSocket 捕获 onClose
事件并重新连接。
有趣的是,Spring repo 中有一些名为 onClose
的方法,所以也许这个问题需要重新审视。
在我的一个项目中,我遇到了类似的情况。 因此,我求助于使用 start() 和 stop() 方法访问 WebSocketManager 作为连接管理器中的 bean class。 我之前为 websocketserver and websocketclient 创建了一个示例项目。刚刚为其添加了重新连接功能。
此外,我并没有在每次连接关闭时都重新连接。仅在close status 1006(异常关闭)、1011(内部错误)和1012(服务重启)时。
工程可以直接下载运行。