gpt4 book ai didi

java - Websocket服务器: Handle close event per session

转载 作者:太空宇宙 更新时间:2023-11-04 11:07:35 26 4
gpt4 key购买 nike

有没有办法处理每个 session 的 websocket 的服务器端关闭事件?这就是我目前的实现方式:

@ServerEndpoint("/ws")
public class WebsocketServerEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Websocket opened");
CustomWebsocketHandler handler = new CustomWebsocketHandler(session); // see below
// ...
}

@OnClose
public void onClose(Session session, CloseReason reason) {
System.out.println("Websocket closed. Reason: " + reason);
}
}

但我想将新的 Session 实例包装在自定义对象内。对于消息,我可以通过 addMessageHandler 将处理程序直接添加到特定 session 。但是如何为该特定 session 上的 onClose 事件添加处理程序?:

class CustomWebsocketHandler {
public CustomWebsocketHandler(Session session) {
session.addMessageHandler((MessageHandler.Whole<String>) this::handleMessage);
// How to hook up close event to handleClose()?
}

private void handleMessage(String message) { /* ... */ }

private void handleClose() { /* ... */ }
}

我的一个想法是跟踪 WebsocketServerEndpoint 中的每个 session 及其各自的 CustomWebsocketHandler 实例,并针对每个关闭事件遍历它们,转发该事件。然而,这非常麻烦并且容易出错:

@ServerEndpoint("/ws")
public class WebsocketServerEndpoint {
private List<Pair<Session, CustomWebsocketHandler>> sessions = new ArrayList<>();

@OnOpen
public void onOpen(Session session) {
// ...
sessions.add(Pair.of(session, handler)); // not hashable I suppose
}

@OnClose
public void onClose(Session session, CloseReason reason) {
// ...
for (Iterator<Pair<Session, CustomWebsocketHandler>> it = sessions.iterator(); it.hasNext(); ) {
Pair<Session, CustomWebsocketHandler> pair = it.next();
if (pair.getLeft() == session) {
pair.getRight().handleClose();
it.remove();
break;
}
}
}
}

在客户端,这很容易,因为每个连接都可以使用自己的 ClientEndpoint 注释类实例:

webSocketContainer.connectToServer(endpointInstance, websocketURI);

服务器端是否存在类似的情况,或者是否可以完全处理每个 session 的服务器端 onClose (最终还有 onError)事件?

最佳答案

默认情况下,会为每个新客户端创建 ServerEndpoint 注释类的新实例。此行为由 ServerEndpointConfig.Configurator#getEndpointInstance 控制方法:

The platform default implementation of this method returns a new endpoint instance per call, thereby ensuring that there is one endpoint instance per client, the default deployment cardinality.

这意味着可以安全地将特定于 session 的状态存储在 WebsocketServerEndpoint 类本身中,而无需手动将 session 与自定义连接实例关联起来:

@ServerEndpoint("/ws")
public class WebsocketServerEndpoint {
private CustomWebsocketHandler handler;

@OnOpen
public void onOpen(Session session) {
handler = new CustomWebsocketHandler(session);
}

@OnClose
public void onClose(Session session, CloseReason reason) {
handler.handleClose();
}
}

此时,将带注释的类 WebsocketServerEndpoint 本身作为所需的 CustomWebsocketHandler 可能会更容易,因为它具有相同的语义:每个连接一个实例并处理 websocket 事件。

关于java - Websocket服务器: Handle close event per session,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46341161/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com