如何获取现有的Websocket实例
我正在使用Websockets(Java EE
7)将消息异步发送到所有连接的客户端的应用程序。每当创建新文章(我的应用程序中的参与模式)时,服务器(Websocket端点)应发送这些消息。
每次建立到websocket端点的连接时,我都会将相应的会话添加到列表中,我可以在外部访问该列表。
但是我遇到的问题是,当我访问所有外部(所有其他业务类)与之连接的客户端创建的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;
}
提前致谢。
回答:
容器会为每个客户端连接创建一个单独的终结点实例,因此您无法做您想做的事情。但是我认为您想要做的是在事件发生时向所有活动的客户端连接发送消息,这非常简单。
本javax.websocket.Session
类有getBasicRemote
检索方法RemoteEndpoint.Basic
,表示与该会话相关的端点实例。
您可以通过调用来检索所有打开的会话Session.getOpenSessions()
,然后遍历它们。该循环将向每个客户端连接发送一条消息。这是一个简单的例子:
@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));
...
}
请参阅有关WebSocket和CDI事件的Java EE 7教程章节。
编辑:修改了@Observer
将事件用作参数的方法。
编辑2:按照@gcvt,以同步方式将循环包装在broadcastArticle中。
编辑3:更新了指向Java EE 7教程的链接。干得好,Oracle。嘘。
以上是 如何获取现有的Websocket实例 的全部内容, 来源链接: utcz.com/qa/420171.html