javax.websocket.Session-getUserProperties()返回哪个映射实现



我目前正在jetty上部署,但我想每个实现都遵循相同的概念。那么它是返回一个HashMap还是ConcurrentHashMap或者其他什么。我试图检查Jetty的WebsocketSession的实现源,但在内部我没有找到用映射初始化用户属性的位置。对于jetty,我可以使用调试器来检查将哪个用户属性实例分配给会话,但这并不能回答其他应用程序服务器是否也会这样做的问题。

有人知道答案吗?SearchWebSites大多返回关于websocket的教程,并且无法得到这个特定问题的答案

Tyrus实现

至于Tyrus,我看了一下TyrusSession.java的实现。您感兴趣的摘录(数字指行):

87   public class TyrusSession implements Session, DistributedSession {
104      private final Map<String, Object> userProperties;
127      TyrusSession(...) {
191          userProperties = new HashMap<String, Object>();
192      }
... }

所以它是一个基本的HashMap。但是,您应该NOT依赖于实现。这就是为什么签名是由Map<String, Object>定义的,而不是由ConcurrentHashMap或任何复杂的东西定义的:

用户属性:

JSR 359第2.1.2节所定义:

开发人员可以使用可通过Session对象上的getUserProperties()调用访问的用户属性映射,将特定于应用程序的信息与特定会话关联起来。websocket实现必须保留此会话数据以便以后访问,直到端点实例上的onClose()方法完成为止。[WSC 2.1.2-2]。在此之后,允许websocket实现丢弃开发人员数据。

JSR的强调

用户属性映射仅特定于给定的websocket会话,因此没有并发访问的意义。你可能有另一个涉及多个会话的对象,但那将是一个你自己的对象,所以你可以决定要使用什么。

一个会话=一个服务器端点实例

我想补充一点,您的服务器端点不是一个单例:每个对等端(会话)应有一个端点实例。来自JSR359第5.1节

除非有一个具有不同生命周期的Java EE组件支持(请参阅第7章),否则容器必须为每个对等点使用一个唯一的端点实例。[WSC-5.1-1]在任何情况下,实现都不得每次调用每个对等点有一个以上线程的端点实例。[WSC-5.1-2]在打开方法完成之前,实现可能不会在端点上调用关闭方法。[WSC-5.1-3]

这保证了每个对等点一次调用一个websocket端点实例的容器线程不会超过一个。[WSC-5.1-4]

简而言之,在websocket设计期间,当处理用户属性时,以及更全局地处理集合时:

  1. 一个会话有自己的实例或@ServerEndPoint
  2. 不要假设websocket是线程安全的
  3. 只依赖规范,不依赖实现

关于javax.websocket.session中用户属性的侧节点:

请注意,userProperties只是实例化的,而不是从任何其他映射中填充的。我强调了这一点,以防您通过扩展ServerEndpointConfig.Configurator使用自定义配置程序:如果您在ServerEndpointConfig.getUserProperties()中放入一些数据,它们将不会自动复制到Session.getUserProperties()

最新更新