gpt4 book ai didi

java - 如何获取现有的 websocket 实例

转载 作者:搜寻专家 更新时间:2023-10-30 21:00:03 24 4
gpt4 key购买 nike

我正在开发一个使用 Websockets (Java EE 7) 向所有连接的客户端异步发送消息的应用程序。每当创建新文章(我的应用程序中的参与模式)时,服务器(Websocket 端点)应该发送这些消息。

每次与 websocket 端点建立连接时,我都会将相应的 session 添加到列表中,我可以从外部访问该列表。

但我遇到的问题是,当我访问这个创建的 websocket 端点时,所有客户端(任何其他业务类)都从外部连接到该端点,我得到了现有实例(如单例)。

所以,你能给我一个方法来获取 websocket 端点的现有实例吗,因为我无法将其创建为新的 MyWebsocketEndPoint() 因为它会在请求时由 websocket 内部机制创建接待客户。

引用:

private static WebSocketEndPoint INSTANCE = null;

public static WebSocketEndPoint getInstance() {
if(INSTANCE == null) {
// Instead of creating a new instance, I need an existing one
INSTANCE = new WebSocketEndPoint ();
}
return INSTANCE;
}

提前致谢。

最佳答案

容器为每个客户端连接创建一个单独的端点实例,因此您无法做您想做的事情。但我认为您要做的是在事件发生时向所有 Activity 的客户端连接发送一条消息,这非常简单。

javax.websocket.Session 类具有 getBasicRemote 方法来检索表示与该 session 关联的端点的 RemoteEndpoint.Basic 实例.

您可以通过调用 Session.getOpenSessions() 检索所有打开的 session ,然后遍历它们。该循环将向每个客户端连接发送一条消息。这是一个简单的例子:

@ServerEndpoint("/myendpoint")
public class MyEndpoint {
@OnMessage
public void onMessage(Session session, String message) {
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()) {
s.getBasicRemote().sendText(message);
}
} catch (IOException ex) { ... }
}
}

但在您的情况下,您可能希望使用 CDI 事件来触发对所有客户端的更新。在这种情况下,您将创建一个 CDI 事件,您的 Websocket 端点类中的一个方法会观察到该事件:

@ServerEndpoint("/myendpoint")
public class MyEndpoint {
// EJB that fires an event when a new article appears
@EJB
ArticleBean articleBean;
// a collection containing all the sessions
private static final Set<Session> sessions =
Collections.synchronizedSet(new HashSet<Session>());

@OnOpen
public void onOpen(final Session session) {
// add the new session to the set
sessions.add(session);
...
}

@OnClose
public void onClose(final Session session) {
// remove the session from the set
sessions.remove(session);
}

public void broadcastArticle(@Observes @NewArticleEvent ArticleEvent articleEvent) {
synchronized(sessions) {
for (Session s : sessions) {
if (s.isOpen()) {
try {
// send the article summary to all the connected clients
s.getBasicRemote().sendText("New article up:" + articleEvent.getArticle().getSummary());
} catch (IOException ex) { ... }
}
}
}
}
}

上面例子中的 EJB 会做类似的事情:

...
@Inject
Event<ArticleEvent> newArticleEvent;

public void publishArticle(Article article) {
...
newArticleEvent.fire(new ArticleEvent(article));
...
}

请参阅 WebSockets 上的 Java EE 7 教程章节和 CDI Events .

编辑:修改了 @Observer 方法以使用事件作为参数。

编辑 2:根据@gcvt,将循环包装在同步的 broadcastArticle 中。

编辑 3:更新了指向 Java EE 7 教程的链接。干得好,甲骨文。嘘。

关于java - 如何获取现有的 websocket 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18481597/

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