5

I think this is more a design specific question, than direct coding issue.

I want to implement a websocket service which serves an updated dataset from a foreign http:// resource to the clients. but i want to have the data available before the first client connects, so @OnLoad notation won't do.

In HttpServlet world I would

@Override public void init() throws...

I could not figure out a suitable way for doing so just using JSR-356. I tried with custom ServerEndpointConfig.Configurator but that does not seem to give me access to method similar to init() from HttpServlet.

So my question is:

Letting the websocket Endpoint class extend HttpServlet gives me access to the init() method and I can place my initial logic there. Is that a suitable way for solving my problem, or have i missed something in JSR-356 which does the job elegantly and without importing mostly unused servlet packages?

Thank you very much!

4

1 回答 1

3

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

我有一个与你类似的问题,我需要让一个 Web 套接字成为 Spring Web 服务的观察者(不要问,我同意你这是一个糟糕的架构问题)。为了使其成为观察者,我必须将其添加到可观察类中,但由于缺乏对网络套接字的初始化,我没有明确的位置添加观察者,将其添加到@OnOpen方法中会在每个新连接上重复添加它。

我找到的唯一解决方案是一种解决方法。通常一个网络套接字类有一个static Set连接到它的对等点,你需要类似的东西来初始化。在构造函数中使用 astatic 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;
    }
}

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

于 2015-02-09T10:02:16.697 回答