jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [JAVASERVERFACES-SPEC_PUBLIC-1396] f:socket for SSE and WebSocket PROPOSAL

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Mon, 7 Dec 2015 19:08:52 +0100

Hi,

Looks great! I noticed there's a bunch of information about the working and
usage of this in the javadoc of this class:
https://github.com/omnifaces/omnifaces/blob/master/src/main/java/org/omnifaces/cdi/push/Socket.java

That one may be a good read for the EG specifically.

Would be great if a version of this can be pushed to the RI before long.
It's been a while since the last commit for a 2.3 feature, and nothing
better to keep the community interested than some actual working code they
can play around with I guess ;)

Kind regards,
Arjan Tijms



On Mon, Dec 7, 2015 at 10:23 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:

> Hi,
>
> Last weekend I developed and added o:socket for OmniFaces, which could be
> used as base for f:socket:
> http://omnifaces.org/docs/javadoc/current/org/omnifaces/cdi/push/Socket.html
> Source code can be found here:
> https://github.com/omnifaces/omnifaces/tree/master/src/main/java/org/omnifaces/cdi/push
> (4 classes).
>
> Some considerations I took are however differ from f:socket:
>
> - I dropped SSE support. As per http://caniuse.com/#feat=websockets vs
> http://caniuse.com/#feat=eventsource the WS enjoy broader support
> (IE/Edge!) and the protocol is also much more efficient than SSE (no
> persistent open connection). A single protocol also keeps server/client
> side code much simpler.
>
> - I dropped proposed widgetvar/autoconnect attributes and instead added
> enabled attribute. It basically controls whether the underlying WS init
> script will be rendered or not. This is evaluated during view render time
> and can be ajax-updated. The socket can be explicitly closed via a public
> script function taking just channel name.
>
> - I dropped proposed onerror attribute and instead added onclose
> attribute. It will also be invoked during onerror and is more useful as the
> CloseEvent is then available which also contains the error code. The script
> is written that way that it's also invoked when WS is not supported (e.g.
> IE6-9), a custom error code of -1 is then passed.
>
> The combination with o:commandScript (similar component is also scheduled
> for JSF 2.3, see spec issue 613) makes it a very nice tool to trigger ajax
> updates via push.
>
> Cheers, Bauke
>
>
>
> On Thu, Sep 3, 2015 at 11:01 PM, Edward Burns <edward.burns_at_oracle.com>
> wrote:
>
>> >>>>> On Mon, 24 Aug 2015 05:31:16 -0700, Edward Burns <
>> edward.burns_at_oracle.com> said:
>>
>> EB> Executive Summary: Ed cites discussion thus far and concludes our
>> EB> next step is to answer this question: How does this feature interact
>> EB> with the JSF request processing lifecycle? In Ed's thinking, it
>> EB> does not. Ed asks Cagatay (or anyone else who knows the answer) to
>> EB> explain how this works for PrimeFaces p:socket.
>>
>> I'm having a hard time resolving the sketches people have been sharing
>> here on the list with the examples of <p:socket> from the PrimeFaces
>> showcase. There are seven examples. Let's take the simplest four of
>> them in turn and ask the question, "How does the usage of p:socket
>> interact with the JSF lifecycle?"
>>
>> Counter <http://www.primefaces.org/showcase/push/counter.xhtml>
>>
>> On first render, the count value is taken from the ApplicationScoped
>> GlobalCounterView bean. When the button is pressed, an Ajax postback
>> happens and an actionListener is invoked. The actionListener method
>> causes a publish() on the PrimeFaces EventBus. The listener for this
>> event is synchronously invoked, which returns the count string, which
>> somehow makes its way to the WebSocket endpoint, which sends it down the
>> WebSocket to the clients. At the same time, the JSF lifecycle yields an
>> Ajax response, but the Ajax response does not contain any visible
>> markup. Rather, the WebSocket connection is used to cause the counter
>> to be updated via jQuery on all browsers currently viewing the same
>> page.
>>
>> Conclusion: the <p:socket> does not interact directly with the JSF
>> lifecycle, it just receives the update from the browser. On the other
>> hand, the dispatching of the event that causes the push to the browser
>> *does* happen during the Ajax request postback.
>>
>> ViewParam <
>> http://www.primefaces.org/showcase/push/viewparam.xhtml?data=foo>
>>
>> On first render, the incoming data=foo query parameter is decode into
>> the <f:viewParam>. During updateModelValues, the value is pushed into
>> the EL expression #{viewParamPush.data}. Before Render Response, the
>> prerender() method is called. This causes the a publish on the
>> PrimeFaces EventBus. The listener for this event is synchronously
>> invoked, which returns the data, which somehow makes its way to the
>> WebSocket endpoint, which sends it down the WebSocket to the clients.
>>
>> Conclusion: the <p:socket> does not interact directly with the
>> lifecycle. On the other hand, the decoding of the viewParam does happen
>> during the full GET request.
>>
>> Notify <http://www.primefaces.org/showcase/push/notify.xhtml>
>>
>> On first render, the simple form gets the two values from the request
>> scoped bean NotifyView. When the button is pressed, an Ajax submit
>> happens, and the action listener NotifyView.send() method is called.
>> This causes a publish to the EventBus. Synchronously on the same thread
>> the listener is invoked which uses the JSONEncoder to convert the
>> FacesMessage to JSON, which is sent to the browser.
>>
>> Consclusion: Same pattern as before.
>>
>> Checkin <http://www.primefaces.org/showcase/mobile/checkin.xhtml>
>>
>> This one uses javascript to set the value of some hidden fields using
>> the browser's current position. This is combined with the value of the
>> text field and sent via an Ajax POST. The publish() method is bound as
>> the actionListener of the button, and this causes a publish to the
>> EventBus. From there the listener for the event receives the Checkin
>> pojo, which is sent to the browser as JSON.
>>
>> Conclusion: Same patterns as before.
>>
>> At this point, I think it is pretty clear that the intended usage of
>> <p:socket> is simply to provide a shorthand for opening up a generic
>> connection between the server and the client and that the data sent over
>> that connection does not have anything to do with the request processing
>> lifecycle.
>>
>> So the bottom line for our design of <f:socket> in JSF 2.3 is that it
>> will follow the example of <p:socket> and not necessarily have anything
>> to do with the JSF requets processing lifecycle.
>>
>> Ed
>>
>>
>> --
>> | edward.burns_at_oracle.com | office: +1 407 458 0017
>> | 44 Business days til JavaOne 2015
>> | 59 Business days til DOAG 2015
>>
>
>