2

JSR-356 でサーバーが開始した WebSocket メッセージをブロードキャストするベスト プラクティスは何ですか?

明確にするために、注釈を使用するときに返信やブロードキャストがどのように機能するかは知って@OnMessageいますが、最初にクライアントからメッセージを受信せずにサーバーからイベントを送信したいと考えています。MessageServerEndpointつまり、以下のコードのインスタンスへの参照が必要だと思います。

次の解決策を見てきましたが、静的メソッドを使用しており、あまりエレガントではありません。

@ServerEndpoint(value = "/echo")
public class MessageServerEndpoint {
    private static Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());

    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        sessions.remove(session);
    }

    // Static method - I don't like this at all
    public static void broadcast(String message) {
        for (Session session : sessions) {
            if (session.isOpen()) {
                session.getBasicRemote().sendText(message);
            }
        }
    }
}

public class OtherClass {
    void sendEvent() {
        MessageServerEndpoint.broadcast("test");
        // How do I get a reference to the MessageServerEndpoint instance here instead?
    }
}
4

1 に答える 1

1

エンドポイント インスタンスを保存できる場所を拡張ServerEndpointConfig.Configuratorしてオーバーライドすることで、問題を解決しました。getEndpointInstance()

public class MyEndpointConfigurator extends ServerEndpointConfig.Configurator
    private Set<MyEndpoint> endpoints = Collections.synchronizedSet(new HashSet<>());

    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
        try {
            T endpoint = endpointClass.newInstance();
            MyEndpoint myEndpoint = (MyEndpoint) endpoint;
            myEndpoint.setConfigurator(this);
            endpoints.add(myEndpoint);
            return endpoint;
        } catch (IllegalAccessException e) {
            throw new InstantiationException(e.getMessage());
        }
    }

    // Call this from MyEndpoint.onClose()
    public void removeInstance(MyEndpoint endpoint) {
        endpoints.remove(endpoint);
    }
}

への参照があるのでMyEndpointConfigurator、すべてのエンドポイントへの参照も持っています。

それはまだハックのように感じますが、うまくいくようです。

于 2014-08-15T07:05:32.820 に答える