当前位置: 首页 > 面试题库 >

如何获取现有的Websocket实例

齐航
2023-03-14
问题内容

我正在使用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。嘘。



 类似资料:
  • Web套接字不仅在Web中而且在移动行业中都发挥着关键作用。Web套接字的重要性如下。 Web套接字(如名称所示)与Web相关。Web由一些浏览器的技术组成; 它是广泛的通信平台,适用于大量设备,包括台式电脑,笔记本电脑,平板电脑和智能手机。 利用Web套接字的HTML5应用程序可以在任何支持HTML5的Web浏览器上运行。 主流操作系统支持Web套接字。移动行业的所有主要参与者都在自己的原生应用

  • 问题内容: 我在与Express运行相同的端口上使用WebSockets 。 我想从刚刚建立并升级到WebSocket的HTTP连接中获取关联的“ sessionID”。 如何才能做到这一点? (我目前通过在页面中发送sessionID解决此问题,但这很丑陋。) 问题答案: 解析Cookie 获取会话ID 获取会话数据

  • 需求:语音转文字(边录边转) 前端负责 传递实时音频 后端负责 将音频准换为文本 请教: 前端采用什么方式实现语音的实时采集并通过webSocket向后端实时不间断发送 采用过js-audio-recorder方式实现过录音、但是获取到音频流后 recorder.getWAVBlob()方法会默认执行recorder.stop()录音停止、导致中断;

  • rank ▲ ✰ vote url 56 390 59 554 url 如何获取实例的类名 如何才能获取一个实例对象的类名? 我想或许the inspect module可以实现,但是好像还没有发现什么能帮我的.或许可以分析__class__成员,但是我不知道怎么用. 你试没试类里的__name__属性?比如x.__class__.__name__或许可以得到你想要的 >>> import ite

  • 我在RFC 6455-Web Socket协议中看到了一个名为IANA注意事项的部分。 它定义了几个要添加到 HTTP 协议中的 HTTP 标头。如 Sec-WebSocket-Key、Sec-WebSocket-Extensions 等。 但我没有在RFC 2616-HTTP 1.1协议中找到这些标头。 那么这些头文件定义可以使用了吗? (我不太熟悉RFC文档是如何组织的。原谅我,这是个愚蠢的问

  • 请问我如何在外部获取websocket 返回的数据呢?并且websoket的值是实时变化的