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

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

From: Kito Mann <kito.mann_at_virtua.com>
Date: Fri, 18 Dec 2015 16:28:45 -0500

FWIW, I strongly believe we should support long polling as an alternative
to WebSocket. JSF is used by lots of big companies that may not be able to
use WebSocket, and having a reliable fallback is important.

___

Kito D. Mann | @kito99 | Author, JSF in Action
Web Components, Polymer, JSF, PrimeFaces, Java EE, and Liferay training and
consulting
Virtua, Inc. | virtua.tech
JSFCentral.com | @jsfcentral
+1 203-998-0403

* Listen to the Enterprise Java Newscast: *http://
<http://blogs.jsfcentral.com/JSFNewscast/>enterprisejavanews.com
<http://ww.enterprisejavanews.com>*


On Fri, Dec 18, 2015 at 1:02 PM, Edward Burns <edward.burns_at_oracle.com>
wrote:

> Thanks for this work and sorry for my inactivity.
>
> >>>>> On Mon, 7 Dec 2015 10:23:22 +0100, Bauke Scholtz <balusc_at_gmail.com>
> said:
>
> B> Hi,
> B> Last weekend I developed and added o:socket for OmniFaces, which could
> be
> B> used as base for f:socket:
> B>
> http://omnifaces.org/docs/javadoc/current/org/omnifaces/cdi/push/Socket.html
> B> Source code can be found here:
> B>
> https://github.com/omnifaces/omnifaces/tree/master/src/main/java/org/omnifaces/cdi/push
> B> (4 classes).
>
> B> Some considerations I took are however differ from f:socket:
>
> B> - I dropped SSE support. As per http://caniuse.com/#feat=websockets vs
> B> http://caniuse.com/#feat=eventsource the WS enjoy broader support
> B> (IE/Edge!) and the protocol is also much more efficient than SSE (no
> B> persistent open connection). A single protocol also keeps server/client
> B> side code much simpler.
>
> For f:socket, I agree to only support websocket. In that case, I
> suggest we rename it to f:websocket. This lets us drop the "transport"
> attribute also.
>
> B> - I dropped proposed widgetvar/autoconnect attributes and instead added
> B> enabled attribute. It basically controls whether the underlying WS init
> B> script will be rendered or not.
>
> This much sounds good.
>
> B> This is evaluated during view render time and can be
> B> ajax-updated.
>
> What can be ajax-updated, the value of the "enabled" attribute? If
> that's the case, there must be a server side UIComponent corresponding
> to f:websocket. Is that the case in your design?
>
> B> The socket can be explicitly closed via a public script function
> B> taking just channel name.
>
> Now we're getting into JS API defining territory. How about we make it
> so when you open a WebSocket with <f:websocket id="foo"> we populate a
> JavaScript associative array named "jsf.websocket" such that
>
> jsf.websockets["foo"]
>
> you get the actual JavaScript WebSocket object? This will have its
> onopen, onerror, onmessage, onclose function references set as described
> in the tag attributes.
>
> B> - I dropped proposed onerror attribute and instead added onclose
> attribute.
> B> It will also be invoked during onerror and is more useful as the
> CloseEvent
> B> is then available which also contains the error code. The script is
> written
> B> that way that it's also invoked when WS is not supported (e.g. IE6-9), a
> B> custom error code of -1 is then passed.
>
> How can you get away with dropping onerror when it's part of the W3C
> WebSocket API? [1]
>
> B> The combination with o:commandScript (similar component is also
> scheduled
> B> for JSF 2.3, see spec issue 613) makes it a very nice tool to trigger
> ajax
> B> updates via push.
>
> OK, we'll take that up over there.
>
> >>>>> On Mon, 7 Dec 2015 19:08:52 +0100, arjan tijms <
> arjan.tijms_at_gmail.com> said:
>
> AT> Would be great if a version of this can be pushed to the RI before
> long.
> AT> It's been a while since the last commit for a 2.3 feature, and nothing
> AT> better to keep the community interested than some actual working code
> they
> AT> can play around with I guess ;)
>
> >>>>> On Mon, 7 Dec 2015 20:56:02 +0100, Michael Müller <
> michael.mueller_at_mueller-bruehl.de> said:
>
> MM> Looks great for pushing data from server to client.
> MM> But how to send data from client to server?
> MM> Do we need something like
> MM> public void receiveMessage?
> MM> Or shall standard socket handling be used?
>
> Rather than Ajax, I think it's more natural to just allow the developer to
> get access to the actual WebSocket, as I proposed above.
>
> >>>>> On Tue, 8 Dec 2015 20:38:10 +0100, Bauke Scholtz <balusc_at_gmail.com>
> said:
>
> B> It would only require a change in PartialViewContext API. It must offer
> a
> B> method which triggers the partial response writer to start and end the
> B> <eval>. Right now this is nowhere available in public API and even not
> in
> B> Mojarra implementation. Directly accessing the PartialResponseWriter to
> B> achieve the <eval> job isn't possible. I'd propose adding
> B> PartialViewContext#getEvalScripts() which returns a mutable
> List<String> so
> B> that the developer can add scripts to <eval> of the <partial-response>.
> B> This allows easily executing scripts on complete of ajax response. Both
> B> OmniFaces and PrimeFaces have an enhanced PartialViewContext
> implementation
> B> which offers this additional method which is ultimately used by
> B> respectively RequestContext#execute() and Ajax#oncomplete(). The
> <o:socket>
> B> uses it to open/close the push channel during ajax requests depending on
> B> its "enabled" attribute.
>
> Yes, I like this proposal. Can you please file a separate JIRA for that
> and open up a discussion thread here citing it?
>
> B> Further the o:socket encodes the push message as JSON string in and the
> B> receiver script parses it back to JSON object before invoking the
> onmessage
> B> function. This JSON step is not necessary, but really nice to have.
> Only,
> B> it may require an internal JSON encoder or perhaps the javax.json API
> B> (which is unfortunately not available on servletcontainers like Tomcat
> and
> B> Jetty on contrary to WebSockets). I could omit the JSON feature and
> leave
> B> it up to the developer. If JSON is not mandatory, it will be easy to
> create
> B> an API and impl for the RI.
>
> I have no problem depending on javax.json. We are an EE spec after all.
>
> >>>>> On Tue, 8 Dec 2015 23:09:45 +0100, arjan tijms <
> arjan.tijms_at_gmail.com> said:
>
> AT> If I understood correctly, JSF 2.3 can depend on pretty much everything
> AT> from the Java EE Web Profile, so this shouldn't be a problem by
> itself. For
> AT> Tomcat and friends it would then be a matter of adding the JSON encoder
> AT> separately, wouldn't it? That's currently how it works for the CDI and
> AT> BeanValidation dependencies.
>
> We can fully depend on EE8. That even means Servlet 4.0. This is a
> departure from all preceding revisions of JSF.
>
> AT> Nevertheless, may be nice to see if some explicit pluggability
> mechanism
> AT> can be used here.
>
> No thank you. We have enough pluggability already.
>
> AT> For an initial version in Mojarra it may be an option to omit JSON
> first,
> AT> and then do the JSON support in a second iteration.
>
> I disagree, let's keep it in.
>
> B> I only wonder if both you and Ed agree on taking over the <o:socket> in
> its
> B> current form for JSF 2.3 <f:socket>. Among others, I omitted the SSE
> B> support as it isn't standardized yet while WS is even backed by a Java
> EE
> B> API (JSR356) which is even implemented in barebones servletcontainers
> like
> B> Tomcat and Jetty. And, some attributes have been reworked to keep it as
> B> simple as possible.
>
> I'd like to get an answer to my question about whether or not there is a
> server side UIComponent for each <f:websocket>. If so, we may have some
> more fundamental architectural differences of opinion.
>
> >>>>> On Thu, 10 Dec 2015 14:49:31 +0100, Bauke Scholtz <balusc_at_gmail.com>
> said:
>
> B> Yes, interpret it as ".. agree on me taking over .." :) Currently still
> B> work in progress, programmatic CDI management is not funny.
>
> See preceding question.
>
> B> Just in case, I made some more changes to OmniFaces socket:
> B> - Added "port" attribute which allows explicitly specifying WS server
> port
> B> number (as it's possible that the very same container runs the WS
> server on
> B> a different port than the HTTP server).
> B> - Endpoint is now lazily programmatically registered on first usage of
> B> o:socket instead than eagerly on startup.
> B> - Endpoint now accepts only connections from predefined channel names
> (the
> B> ones specified in o:socket channel attribute), all others will just be
> B> aborted by an exception.
>
> These are fine.
>
> >>>>> On Fri, 11 Dec 2015 12:50:35 +0000, Bauke Scholtz <balusc_at_gmail.com>
> said:
>
> B> It has in the meanwhile been further improved though. For a live demo,
> see
> B> also http://snapshot.omnifaces.org/push/socket
>
> This is a lot of momentum!
>
> >>>>> On Wed, 16 Dec 2015 20:55:37 +0100, Bauke Scholtz <balusc_at_gmail.com>
> said:
>
> B> While developing and testing the o:socket I wasn't satisfied with how WS
> B> session and HTTP session interacted with each other (among others, HTTP
> B> session timeout doesn't trigger a re-handshake of the WS session,
> causing
> B> its endpoint config to still refer the old HTTP session), so I have
> further
> B> improved the o:socket to be less dependent on that and made even more
> B> Portlet friendly as there are no hard javax.servlet dependencies
> B> anymore.
>
> Yes, those two session objects are entirely disjoint, and necessarily
> so. To access the HttpSession from the WebSocket session, you must save
> it aside during the handshake. Perhaps we can make that easier so you
> can have access to it automatically?
>
> B> For security, there's currently in o:socket only a servlet filter in
> place
> B> which should return 400 on WS handshake requests on non-existing
> channels:
> B>
> https://github.com/omnifaces/omnifaces/blob/master/src/main/java/org/omnifaces/cdi/push/SocketChannelFilter.java
> .
>
> B> As this isn't Portlet compatible, I'm for Mojarra's f:socket thinking to
> B> programmatically add /javax.faces.push/* to servlet mapping and then do
> the
> B> job in FacesServlet instead. Would this be OK for Portlets too? Neil? Or
> B> perhaps I should append the current FacesServlet mapping to the push URL
> B> and then inspect the presence of the /javax.faces.push prefix as
> currently
> B> also done for /javax.faces.resource requests.
>
> This is my biggest beef with p:socket. It's a pain to set up. I'd
> really like to make it so you don't have to do any additional set up.
> We can bake this functionality straight into the FacesServlet.
>
> Can you rework your impl to do it that way?
>
> Ed
>
> --
> | edward.burns_at_oracle.com | office: +1 407 458 0017
>
>
> [1]
> http://www.w3.org/TR/2011/WD-websockets-20110419/#the-websocket-interface
>