Один EJB отвечает за логику и множество клиентов - PullRequest
1 голос
/ 08 марта 2012

Я новичок в Java EE и застрял с проблемой, описанной ниже, я буду очень рад, если вы сможете мне помочь.

Мне нужно реализовать некоторую логику (на основе конечного автомата) на сервере. Как я понимаю, я должен реализовать это как EJB, верно? Проблема заключается в том, что один клиент должен иметь возможность создавать такой «объект», а другие клиенты должны иметь возможность подключаться к нему. Когда все клиенты отключают объект формы, он должен быть уничтожен.

Кроме того, такой объект выполняет некоторые операции в цикле, и он должен иметь возможность уведомлять подключенных клиентов о конкретных изменениях.

До сих пор я узнал, что EJB ориентирован на однопользовательский сеанс или для обмена сообщениями. Ни один из них не соответствует моим требованиям.

Любые советы, как разработать приложение для моей проблемы? Я должен придерживаться Java EE 6.

Ответы [ 3 ]

2 голосов
/ 17 марта 2012

Как предполагает @ Андре, объект с конечным автоматом должен быть классом @ApplicationScoped или @Singleton в зависимости от того, нужна ли вам функция EJB или нет, на которую клиенты могут зарегистрироваться:

@ApplicationScoped
public class StateMachine {
    private List<Client> clients;

    @PostConstruct
    public void create() {
        clients = new LinkedList<Client>();
    }

    public void register(Client client) {
        clients.add(client);
    }

    public void unregister(Client client) {
        clients.remove(client);
        if (clients.isEmpty()) {
            reset();
        }
    }

    public void reset() {
        // resets the singleton, because the container manages its life-cycle
    }
}

Класс Client может относиться к классу @SessionScoped, который действует до тех пор, пока клиентский сеанс действителен. По первому запросу класса сессий регистрируется в синглтоне. Затем вы можете информировать клиентов о событиях, просматривая список. Всякий раз, когда требуются актуальные данные, класс Client можно запрашивать с помощью запроса.

@SessionScoped
public class Client {
    @Inject private StateMachine machine;

    @PostConstruct
    public void registerToStateMachine() {
        machine.register(this);
    }

    @PreDestroy
    public void unregisterFromStateMachine() {
        machine.unregister(this);
    }

    public void handleEvent(/*..*/) {}

    public /*..*/ query() {}
}

Имейте в виду, что вы не можете отправить CDI Event<> из @ApplicationScoped в @SessionScoped объектов, поскольку их контекст недоступен в контексте приложения.

1 голос
/ 11 марта 2012

Вы можете попробовать использовать JMS javax.jms.Topic здесь, где один из ваших клиентов может опубликовать сообщение, а другие могут его прослушать.

Поэтому все подписанные клиенты на эту конкретную тему будут получать уведомления при каждом добавлении нового сообщения.

0 голосов
/ 08 марта 2012

Попробуйте превратить ваш «объект» в одноэлементное событие, запускающее ejb для ваших подключенных клиентов - наблюдателей cdi.

...