gpt4 book ai didi

java - JSR-356 中服务器发起的 WebSocket 广播

转载 作者:太空宇宙 更新时间:2023-11-04 14:38:11 25 4
gpt4 key购买 nike

在 JSR-356 中广播服务器启动的 WebSocket 消息的最佳实践是什么?

为了澄清,我知道使用 @OnMessage 注释时回复甚至广播是如何工作的,但我想从服务器发送事件而不首先从客户端接收消息。换句话说,我想我需要在下面的代码中引用 MessageServerEndpoint 实例。

我见过以下解决方案,但它使用静态方法,不太优雅。

@ServerEndpoint(value = "/echo")
public class MessageServerEndpoint {
private static Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());

@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}

@OnClose
public void onClose(Session session, CloseReason closeReason) {
sessions.remove(session);
}

// Static method - I don't like this at all
public static void broadcast(String message) {
for (Session session : sessions) {
if (session.isOpen()) {
session.getBasicRemote().sendText(message);
}
}
}
}

public class OtherClass {
void sendEvent() {
MessageServerEndpoint.broadcast("test");
// How do I get a reference to the MessageServerEndpoint instance here instead?
}
}

最佳答案

我通过扩展 ServerEndpointConfig.Configurator 并覆盖 getEndpointInstance() 解决了这个问题,我可以在其中保存端点实例:

public class MyEndpointConfigurator extends ServerEndpointConfig.Configurator
private Set<MyEndpoint> endpoints = Collections.synchronizedSet(new HashSet<>());

@Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
try {
T endpoint = endpointClass.newInstance();
MyEndpoint myEndpoint = (MyEndpoint) endpoint;
myEndpoint.setConfigurator(this);
endpoints.add(myEndpoint);
return endpoint;
} catch (IllegalAccessException e) {
throw new InstantiationException(e.getMessage());
}
}

// Call this from MyEndpoint.onClose()
public void removeInstance(MyEndpoint endpoint) {
endpoints.remove(endpoint);
}
}

由于我引用了 MyEndpointConfigurator,因此我也引用了所有端点。

它仍然感觉像是黑客攻击,但似乎可以解决问题。

关于java - JSR-356 中服务器发起的 WebSocket 广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25301406/

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