PushContext ничего не отправляет в открытый сокет, если я не использую какой-либо компонент команды JSF для вызова метода отправки. - PullRequest
0 голосов
/ 07 августа 2020

Рассказ:

Я работаю над сайтом размещения. Я хочу сделать рендеринг Ajax на странице в зависимости от смены дня. Если я использую командный компонент JSF, например командную кнопку, WebSocket Pu sh будет работать. Но если я использую наблюдаемый bean-компонент, чтобы запросить bean-компонент-наблюдатель для вызова метода pushContext.send, метод onDayChange вызывается через одну минуту, и в этом методе нет исключения, кроме элемента AccommodationSearchFields не отображается, и поэтому атрибут data-currentDate не изменяется, и когда я смотрю на Инструменты веб-разработчика> Сеть> XHR, записи нет.

Что я сделано:

EJB Bean:

@Singleton @Lock(LockType.READ)
public class DateScheduled implements NextDayObservable{
    // Other member variables
    private final ScheduledExecutorService scheduledExecutorService;
    private final List<NextDayObserver> dateObservers;

    public DateScheduled(){
        /*this.now = LocalDateTime.now();
        this.nextDay = LocalDateTime.now()
                                    .withHour(00)
                                    .withMinute(0)
                                    .withSecond(1)
                                    .withNano(0);
       scheduledExecutorService.scheduleAtFixedRate(
            () -> { notifyObserversOfDayChange(); },
            now.until(nextDay, ChronoUnit.MILLIS),
            TimeUnit.DAYS.toMillis(1),
            TimeUnit.MILLISECONDS
        );*/        
        this.scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(
            () -> { notifyObserversOfDayChange(); },
            10000,
            TimeUnit.DAYS.toMillis(1),
            TimeUnit.MILLISECONDS
        );
        this.dateObservers = new ArrayList<>();
    }

    @Override @Lock(LockType.WRITE)
    public void registerObserver(final NextDayObserver dateObserver){
        if(dateObservers.indexOf(dateObserver) < 0){
            dateObservers.add(dateObserver);
        }
    }

    @Override @Lock(LockType.WRITE)
    public void removeObserver(final NextDayObserver dateObserver){
        dateObservers.remove(dateObserver);
    }

    @Override
    public void notifyObserversOfDayChange(){
        dateObservers.forEach(
            dateObserver -> { dateObserver.onDayChange(); }
        );
    }
}

Backing Bean:

@Named @ApplicationScoped
public class MainTemplateMB extends BaseManagedBean implements Serializable, NextDayObserver{
    private static final long serialVersionUID = 1L;

    // Other member variables
    
    private String currentDate;
    
    @EJB
    protected NextDayObservable nextDayObservable;
    
    @Inject @Push
    private PushContext pushContext;
    
    // Other member variables
    
    public MainTemplateMB(){
        // Other Initializations
        this.currentDate = "";
    }

    @PostConstruct
    private void initialization(){
        // Other Initializations
        nextDayObservable.registerObserver(this);
        currentDate = DateUtility.getCurrentYear() + "." + (DateUtility.getCurrentMonth() -1) + "." + DateUtility.getCurrentDay() + "." + DateUtility.getMonthFirstDay()+ "." + DateUtility.getLastMonthMaximumDays();
    }

    // Other Methods
    
    @Override
    public void onDayChange(){
        // currentDate has changed for testing
        currentDate = DateUtility.getCurrentYear() + "." + ( DateUtility.getCurrentMonth() + 1 ) + "." + DateUtility.getCurrentDay() + "." + DateUtility.getMonthFirstDay()+ "." + DateUtility.getLastMonthMaximumDays();
        pushContext.send("dayChange");
    }
}

The MainTemplate.x html:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE html>

<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:jsf="http://xmlns.jcp.org/jsf"
    xmlns:jsfc="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    lang="#{sessionTools.language}" xml:lang="#{sessionTools.language}">
    
    <jsfc:view locale="#{sessionTools.locale}" contentType="text/html">
        <head>
            .
            .
            .
            
        </head>

        <body>
            <div id="wrapper">
                .
                .
                .

                <section jsf:id="accommodationSearchFields" data-currentDate="#{mainTemplateMB.currentDate}">
                    <form jsf:id="accommodationSearchForm" method="GET" autocomplete="off">
                        .
                        .
                        .
                        <input class="button field roundedCorners4" type="submit" value="#{mainTemplateProp.search}" jsf:action="#{mainTemplateMB.goToTheCity()}" />
                <!--  <input class="button field roundedCorners4" type="submit" value="#{mainTemplateProp.search}" jsf:action="#{mainTemplateMB.onDayChange()}">
                            <jsfc:ajax />
                        </input> -->
                        .
                        .
                        .
                    </form>
                </section>
                .
                .
                .


            </div>
            <form jsf:id="dayChangeWebSocket">
                <jsfc:websocket channel="pushContext">
                    <jsfc:ajax event="dayChange" render=":accommodationSearchFields" />
                </jsfc:websocket>
            </form>
        </body>
    </jsfc:view>
</html>

После переключения на шаблон JEE Observer:

EJB Bean:

@Singleton @Startup @Lock(LockType.READ)
public class DateScheduled{
    // Other member variables
    private final ScheduledExecutorService scheduledExecutorService;

    @Inject
    private BeanManager beanManager;

    public DateScheduled(){
        /*this.now = LocalDateTime.now();
        this.nextDay = LocalDateTime.now()
                                    .withHour(00)
                                    .withMinute(0)
                                    .withSecond(1)
                                    .withNano(0);
       scheduledExecutorService.scheduleAtFixedRate(
            () -> { notifyObserversOfDayChange(); },
            now.until(nextDay, ChronoUnit.MILLIS),
            TimeUnit.DAYS.toMillis(1),
            TimeUnit.MILLISECONDS
        );*/        
        this.scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(
            () -> { notifyObserversOfDayChange(); },
            60000,
            TimeUnit.DAYS.toMillis(1),
            TimeUnit.MILLISECONDS
        );
    }

    public void notifyObserversOfDayChange(){
        beanManager.fireEvent("Hello");
    }
}

Подложка:

@Named @ApplicationScoped
public class MainTemplateMB extends BaseManagedBean implements Serializable{
    private static final long serialVersionUID = 1L;

    // Other member variables

    private String currentDate;


    @Inject @Push
    private PushContext pushContext;

    // Other member variables

    public MainTemplateMB(){
        // Other Initializations
        this.currentDate = "";
    }

    @PostConstruct
    private void initialization(){
        // Other Initializations
        currentDate = DateUtility.getCurrentYear() + "." + (DateUtility.getCurrentMonth() -1) + "." + DateUtility.getCurrentDay() + "." + DateUtility.getMonthFirstDay()+ "." + DateUtility.getLastMonthMaximumDays();
    }

    // Other Methods

    public void onDayChange(@Observes String message){
        // currentDate has changed for testing
        currentDate = DateUtility.getCurrentYear() + "." + ( DateUtility.getCurrentMonth() + 1 ) + "." + DateUtility.getCurrentDay() + "." + DateUtility.getMonthFirstDay()+ "." + DateUtility.getLastMonthMaximumDays();
        pushContext.send("dayChange");
    }
}

Рабочие инструменты:

. Apache TomEE Plus 8.0.3

. Apache IDE NetBeans 12.0

Вопросы:

  1. Я что-то не так?
  2. В чем проблема?
  3. Как решить проблему?

1 Ответ

0 голосов
/ 10 августа 2020

Я решил проблему.

Когда я добавил клиентское событие onopen в <f:websocket>, я понял, что сокет не открывается. Я наткнулся на этот отличный ответ во время поиска: { ссылка }.

причина номер 8:

Если вы используете Ajax через JSF 2.x <f:ajax> или, например, PrimeFaces <p:commandXxx>, убедитесь, что у вас есть <h:head> в главном шаблоне вместо <head>. В противном случае JSF не сможет автоматически включать необходимые файлы JavaScript, содержащие функции Ajax. Это приведет к ошибке JavaScript типа «mojarra is not defined» или «PrimeFaces is not defined» в консоли JS браузера.

Теперь я вижу, что я должен использовать решить проблему. Спасибо Balus C.

Но я не понимаю, почему нажатие кнопки команды работает, а вызов метода наблюдателя - нет? Учитывая, что я не видел ошибки JavaScript в консоли.

...