Java EE7 websocket初始化 - 在第一个@OnOpen之前实现逻辑

时间:2014-05-05 10:09:23

标签: java websocket glassfish-4 java-ee-7 tomcat8

我认为这更像是一个设计特定的问题,而不是直接编码问题。

我想实现一个websocket服务,该服务提供从外部http://资源到客户端的更新数据集。 但我想在第一个客户端连接之前获得数据,因此@OnLoad表示法不会这样做。

HttpServlet世界,我会

@Override public void init() throws...

我只是使用JSR-356找不到合适的方法。 我尝试使用自定义ServerEndpointConfig.Configurator,但似乎无法访问init()中与HttpServlet类似的方法。

所以我的问题是:

让websocket Endpoint类扩展HttpServlet使我能够访问init()方法,并且可以将初始逻辑放在那里。 这是解决我的问题的合适方式,还是我错过了JSR-356中的一些优点,而且没有导入大部分未使用的servlet包?

非常感谢!

1 个答案:

答案 0 :(得分:3)

每次通过@ServerEndpoint("/myEndPoint")创建新连接时,都会实例化注释为@OnOpen的类。它不是static类,也不是单例(例如,不像Spring @Service)。

我遇到了类似的问题,我需要将一个Web套件作为Spring Web服务的观察者(不要问,我和你在一起这是一个糟糕的架构问题)。为了使它成为一个观察者,我必须将它添加到可观察的类中,但是由于缺少web插座的初始化,我没有明确的位置添加观察者,将其添加到@OnOpen方法会在每个新连接上重复添加它。

我找到的唯一解决方案是解决方法。通常,Web套接字类具有连接到它的static Set个对等体,您需要类似的初始化。在构造函数中使用static blockstatic标志。在我的情况下,我解决了:

private static boolean observerFlag = false;
private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());

public MyWebSocket() {
    if (!observerFlag) {
        observable.addObserver(this);
        observerFlag = true;
    }
}

并删除观察者:

@OnClose
public void onClose(Session peer) {
    peers.remove(peer);
    if (peers.isEmpty()) {
        observable.deleteObserver(this);
        observerFlag = false;
    }
}

我重申这是一种解决方法,我认为有更优雅的解决方案。