2

I am using Primefaces and p:poll because I want to navigate to another page when the poll stops after a condition comes true. On both of the pages the same conversation bean is used. (In fact there are three pages with that use this bean).

But I do not know how to pass as parameter the conversation Id when the poll stops, the way that would be passed if there was a link or button, since f:param cannot be used with p:poll.

Any help would be appreciated.

Thanks in advance.

nickalven
  • 23
  • 3
  • 2
    Tried looking into web sockets? – Jasper de Vries Jul 15 '20 at 06:00
  • I think these two questions might help you: [Stop Ajax Polling](https://stackoverflow.com/questions/12213764/stopping-ajax-polling-in-jsf-primefaces) and [FlowScope](https://stackoverflow.com/questions/28240734/advantages-of-using-jsf-faces-flow-instead-of-the-normal-navigation-system) – fuggerjaki61 Jul 15 '20 at 06:56
  • Thank you @fuggerjaki61 and Jasper de Vries for your answers. I have already managed to stop the poll when a condition comes true in the bean. The problem is that I do not know how to pass as parameter the conversationId. I may try the flowscope option.Regarding the web socket I am not familiar with them. But if the flowscope does not work I will look at it. – nickalven Jul 15 '20 at 08:30
  • What are you trying to say with `conversation id`? See [this example](https://stackoverflow.com/questions/7788430/how-does-jsf-2-conversationscope-work) of a `ConversationScoped` Wizard – fuggerjaki61 Jul 15 '20 at 09:35
  • @fuggerjaki61 you are correct. Iwas confused by [this example](https://www.javacodegeeks.com/2013/04/java-ee-cdi-conversationscoped-example.html). Thank you. – nickalven Jul 15 '20 at 13:32

1 Answers1

1

I think you got two problems:

  1. How to make a multi-page wizard?
  2. How to check if a task (search) is finished?

How to make a multi-page wizard?

I think that is not your main problem and you already got a solution. This is just for the sake of completness.

You can either use a flow or a conversation (I would use this).


How to check if a task (search) is finished?

For this you also got a solution that is similar to this.

But as @Jasper_de_Vries said in the comments a websocket has a way better performance than a p:poll.


So here's my solution for the second problem:

Demo XHTML file:

<h:form>
    <!-- must be in form when it has nested f:ajax's -->
    <f:websocket channel="demo" scope="view">

        <!-- renders the form and the 'someId' component -->
        <!-- when receives 'complete' message -->
        <f:ajax event="complete" render="@form :someId" />
    </f:websocket>    

    <!-- display result here -->
</h:form>

<xy:whatever id="someId">
    <!-- display result here -->
</xy:whatever>

And your bean:

@Named
@ConversationScoped
public class Demo {

    @Inject
    private SomeService service;

    @Inject @Push
    private PushContext demo; // variable name must match the channel name

    private Result result; // getter + setter

    // conversation utilities, etc.
    
    private void sendMessage() {
        demo.send("complete"); // this is the whole magic
    }

    public void startLongTask() {
        service.startLongTask(/* parameters */, result -> {
            // this runs when the callback is accepted
            this.result = result;
            sendMessage();
        });
    }
}

SomeService:

@Stateless/@Stateful
public class SomeServiceService {

    @Asynchronous
    public void startLongTask(/* parameters*/, Consumer<Result> callback) {
        // very long task ...

        callback.accept(result);
    }
}

Basically when the user clicks the button a long task (e.g. a search) is started. When the service completes it will invoke the callback and the UI is updated.

The f:websocket is a feature of JSF 2.3. If you aren't using JSF 2.3 look at the Omnifaces Websocket o:websocket.

fuggerjaki61
  • 822
  • 1
  • 11
  • 24