0

サーバーに対して20秒ごとにRESTful GETリクエストを行い、返されたデータを表示する必要があるJSF + Primefaces Web Appに取り組んでいます。これは現在、「10 秒ごと」の部分を除いて機能します。コマンド ボタンをクリックして、データを取得して表示できます。ScheduledExecutorService で繰り返しを実装しようとしました。commandButton をクリックすると、バッキング関数が 10 秒ごとに実行されます (これは System.out.println の出力で確認できます)。以下は私のコードです:

HTML (これはフォーム内に埋め込まれます)

<p:commandButton id="andon_layout--board0--loadboard0"
    value="Load board"
    actionListener="#{decryptionBean.loadBoardListen0}"
    update="dataPanelGrid" />
<div id="andon_layout--board0--display_div"
    class="ui-datatable ui-widget ">
    <h:panelGrid id="dataPanelGrid"
        columns="#{decryptionBean.displayBoardArray[0].datatableNumberOfCols}"
        headerClass="ui-datatable ui-widget-header ">
        <f:facet name="header">
            <h:outputText
                value="#{decryptionBean.displayBoardArray[0].locationName}" />
        </f:facet>
        <c:forEach var="row"
            items="#{decryptionBean.displayBoardArray[0].displayData}">
            <c:forEach var="value" items="#{row}">
                <div class="ui-dt-c">#{value}</div>
            </c:forEach>
        </c:forEach>
    </h:panelGrid>
</div>

ジャワ

@ManagedBean
@ViewScoped
public class DecryptionBean implements Serializable {
...

private Updater left = new Updater(0);
public void loadBoardListen0(ActionEvent event){
    left.stopBoardLoading();
    left.beginBoardLoading();
}

public final class Updater {

    @PreDestroy
    public void destroy() {
        fScheduler.shutdownNow();
    }

    private ScheduledExecutorService fScheduler;
    //
    private long fDelayBetweenRuns = 10;
    int boardNumber;

    /**
     * If invocations might overlap, you can specify more than a single
     * thread.
     */
    private int NUM_THREADS = 1;
    public int isRunning = 0;
    private boolean DONT_INTERRUPT_IF_RUNNING = false;
    private ScheduledFuture<?> loadBoardFuture;
    private class BoardLoaderTask implements Runnable {
        private int boardNumber;

        public BoardLoaderTask(int boardNumber) {
            this.boardNumber = boardNumber;
        }

        public void run() {
            DecryptionBean.this.loadBoard(boardNumber);
        }
    }

    public Updater(int boardNumber){
        this.boardNumber = boardNumber;
        fScheduler = Executors.newScheduledThreadPool(NUM_THREADS);
    }

    void beginBoardLoading(){
        if(isRunning == 1){
            this.stopBoardLoading();
        }
        isRunning = 1;          
        Runnable boardLoaderTask = new BoardLoaderTask(this.boardNumber);
        loadBoardFuture = fScheduler.scheduleWithFixedDelay(boardLoaderTask,
                0, fDelayBetweenRuns, TimeUnit.SECONDS);
    }

    void stopBoardLoading(){
        if(isRunning == 1){
        isRunning = 0;
        Runnable stopBoard = new StopLoadingTask(loadBoardFuture);
        fScheduler.schedule(stopBoard, 0, TimeUnit.SECONDS);
        }
        isRunning = 0;
    }

    private class StopLoadingTask implements Runnable {
        StopLoadingTask(ScheduledFuture<?> aSchedFuture) {
            fSchedFuture = aSchedFuture;
        }

        private ScheduledFuture<?> fSchedFuture;

        @Override
        public void run() {
            // TODO Auto-generated method stub
            fSchedFuture.cancel(DONT_INTERRUPT_IF_RUNNING);
        }
    }
}

loadBoard(int boardNum) は一種の大きな関数なので、ここには投稿していませんが、必要と思われる場合は投稿します。

問題はp:commandbutton update属性に起因しているように思えます.dataPanelGridは、最後ではなく、の開始時に更新されているようloadBoardListen0です。明確にするために: バッキング機能は最初のクリックで実行されますが、2 回目、3 回目、4 回目などで GUI を更新するだけです。前もって感謝します!

編集 1: 私は現在、PrimePush とソケットを使用してこれを実行しようとしていますが、そこでも問題が発生しています。これをコードに追加しました: HTML <p:socket onMessage="handleMessage" channel="/IPVS" autoConnect="false"/> ...

function handleMessage(data) {
    console.log("data received: " + data);
    var elm = "andon_layout--board" + data + "--display_div";
    elm.style.display="none";
    var redrawFix = elm.offsetHeight;
    elm.style.display="block";
}

JAVA (loadBoard(int) の最後)

System.out.println("Loading data... no exceptions thrown");
System.out.println("context created");
PushContextFactory.getDefault().getPushContext().push("/IPVS", Integer.toString(displayBoardNum));
System.out.println("Just pushed to /IPVS");

コードを実行しようとすると、PushContextFactory 行で停止します。私が得る出力は次のとおりです。

Loading data... no exceptions thrown
context created

そして、それ以上はありません。これにより、ループが実行されなくなります。私はまだ ScheduledExecutorService を使用しており、タスクが完了するたびにデータをプッシュしようとしていることに注意してください。何か案は?

4

1 に答える 1