Объединение нескольких конечных точек WebSockets в Java EE 7

Я использую GlassFish Server 4.1/Java EE 7. Таким образом, реализация Tyrus WebSocket легко доступна из коробки.

В приложении Java EE есть сценарий, в котором пользователи и администратор совместно выполняют операции CRUD. Операция «вставка» выполняется зарегистрированными пользователями, а остальные операции выполняются администратором по мере необходимости.

Например, отзыв отправляется (таким образом, вставляется через связанный с ним объект JPA Feedback) зарегистрированными пользователями (только после входа в систему). «Обновление» (в основном только testimonials) и «удаление» выполняются администратором по мере необходимости (в его собственной сессии).

Следовательно, эти операции выполняются в разных сеансах, требующих разных аутентификаций/авторизаций. Для этого требуются две разные конечные точки WebSockets, например:

@ServerEndpoint("/Admin/Push")

и

@ServerEndpoint("/User/Push")

Вместо использования двух разных классов, таких как

@ServerEndpoint("/Admin/Push") // This is a secured endpoint requiring admin's privileges.
public final class AdminPush {

    private static final Set<Session> sessions = new LinkedHashSet<Session>();

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

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

    @OnMessage
    public void onMessage(String text) {
        // Notify all users.
        // Since modifications to entities are done on the server side,
        // it is basically another synchronized static method notifying all users.
    }
}

и

@ServerEndpoint("/User/Push") // This is a secured endpoint requiring user's privileges.
public final class UserPush {

    private static final Set<Session> sessions = new LinkedHashSet<Session>();

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

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

    @OnMessage
    public void onMessage(String text) {
        // Notify all users.
        // Since modifications to entities are done on the server side,
        // it is basically another synchronized static method notifying all users.
    }
}

разрешено ли объединять их в один класс, например?

@ServerEndpoint("/Admin/Push")
@ServerEndpoint("/User/Push")
public final class Push {}

Теоретически это всего лишь одна мысль сказать, допустимо ли совмещать их таким воображаемым образом или нет. Практически это, очевидно, ошибка времени компиляции, поскольку @ServerEndpoint не является повторяемой аннотацией.

В любом из вышеперечисленных случаев пользователи уведомляются, когда что-то изменяется в объектах Feedback JPA (обновление в реальном времени через WebSockets) либо администратором, либо пользователями. Feedback общедоступен для всех пользователей, включая анонимных, но может быть представлен только зарегистрированными пользователями (он также периодически обновляется, но это отдельная история).


person Tiny    schedule 04.09.2015    source источник
comment
Получили ли вы какое-либо решение для этого, я также хочу сделать что-то подобное   -  person Teocci    schedule 19.07.2016
comment
@Teocci: К сожалению, нет. Вместо этого я создал отдельные конечные точки, как показано во фрагментах.   -  person Tiny    schedule 19.07.2016
comment
Я подумал и пришел к возможному решению. Пожалуйста, дайте мне знать, если есть какой-либо недостаток   -  person Teocci    schedule 20.07.2016


Ответы (1)


Вероятно, вы можете сделать что-то вроде:

@ServerEndpoint("/{profile}/push")
public final class Push {}

Или, с точки зрения разделения бизнеса, вы должны создать один или несколько классов для управления сеансами или общими операциями, а классы точек входа должны вызывать только эти общие методы. Что-то вроде:

@ServerEndpoint("/admin/push")
public final class Admin {
    @OnOpen
    public void onOpen(Session session) {
        // Call session manager
    }
}

@ServerEndpoint("/user/push")
public final class User {
    @OnOpen
    public void onOpen(Session session) {
        // Call session manager
    }
}

public class SessionManager {
    // Your methods
}

Просто пара идей.

person fjavierm    schedule 05.09.2015
comment
Первый подход с использованием javax.websocket.server.PathParam не может быть использован, так как он может разрешить что угодно в параметре пути. Таким образом, любой пользователь может легко установить соединение с этой конечной точкой с помощью JavaScript API. (Это больше не безопасно, если указанному URI разрешено быть динамическим). - person Tiny; 05.09.2015