容器会为每个客户端连接创建一个单独的终结点实例,因此您无法做您想做的事情。但是我认为您想要做的是在事件发生时向所有活动的客户端连接发送消息,这非常简单。
本
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将执行以下 *** 作:
...@InjectEvent<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。嘘。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)