]
Val Blant updated RF-13674:
---------------------------
Attachment: RichFacesPushFixFilter.java
In the mean time, this filter can be used as a workaround.
Note that it does not fix the problem entirely! It makes _<a4j:push />_ *kind of*
work
on WebLogic. Sometimes when long-polling connection times out, the client does not issue
the next request, so push stops working until the page is refreshed.
Could be another problem with the ancient Atmosphere version used by RichFaces.
To register the filter:
{code:xml|title=web.xml}
<filter>
<filter-name>RichFacesPushFixFilter</filter-name>
<filter-class>ca.gc.agr.pushtest.RichFacesPushFixFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>RichFacesPushFixFilter</filter-name>
<url-pattern>/__richfaces_push</url-pattern>
</filter-mapping>
{code}
a4j:push broken on WebLogic 12c
-------------------------------
Key: RF-13674
URL:
https://issues.jboss.org/browse/RF-13674
Project: RichFaces
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: component-push/poll
Affects Versions: 4.2.0.Final
Environment: WebLogic 12c
Reporter: Val Blant
Attachments: atmosphere-weblogic12c-bug-0.8.4-sources.jar,
atmosphere-weblogic12c-bug-0.8.4.war, RichFacesPushFixFilter.java
<a4j:push /> works properly on Tomcat 7, but fails on WebLogic 12c.
{code:title=Page.xhtml|borderStyle=solid}
<a4j:push address="systemLinks" >
<a4j:ajax event="dataavailable" render="systemLinksPanel" />
</a4j:push>
<a4j:outputPanel id="systemLinksPanel">
stuff here
</a4j:outputPanel>
{code}
{code:title=Java Code}
TopicKey topicKey = new TopicKey("systemLinks");
TopicsContext topicsContext = TopicsContext.lookup();
topicsContext.publish(topicKey, "fly, you fools!");
{code}
On Tomcat 7 this work perfectly, and always refreshes '_systemLinksPanel_' when
data is published.
On Weblogic 12c the data is not flushed correctly. If you use Wireshark, you'd see
the following response coming back from the server:
{panel:title=Tomcat 7}
3b
<"topic":"systemLinks","data":"fly, you
fools!","number":0>
0
{panel}
{panel:title=Weblogic 12c}
003b
<"topic":"systemLinks","data":"fly, you
fools!","number":0>
{panel}
*Note the missing zero terminator line in the WebLogic response!*
I narrowed down the problem to the following:
{code:title=org.richfaces.application.push.impl.RequestImpl}
public synchronized void onBroadcast(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
MessageDataScriptString serializedMessages = (MessageDataScriptString)
event.getMessage();
getSession().clearBroadcastedMessages(serializedMessages.getLastSequenceNumber());
hasActiveBroadcaster = false;
if (isPolling()) {
event.getResource().resume(); // <= THIS LINE
} else {
postMessages();
}
}
{code}
There is nothing wrong with this in principle, but it does not work due to a bug in
Atmosphere 0.8.4. Calling _AtmosphereResource.resume()_ at this point seems reasonable,
since it is supposed to properly finish/commit the _HttpServletResponse_. However, this
does not work on WebLogic 12c and leads to incorrectly flushed data demonstrated above.
The underlying problem seems to be the fact that _AtmosphereResource.resume()_ method
interrupts the thread which flushed the socket Writer before a call to
_asyncContext.complete()_ is made:
{code}
public AtmosphereResource resume() {
....
if (!b.isDestroyed()) {
b.removeAtmosphereResource(event.getResource());
}
....
asyncSupport.action(this); // <= This is where asyncContext.complete() is called
}
{code}
I have verified that calling _asyncContext.complete()_ before we clean up Atmosphere
resources fixes the problem.
Here's the fix, which needs to go into _RequestImpl.onBroadcast_:
{code:title=org.richfaces.application.push.impl.RequestImpl}
public synchronized void onBroadcast(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
..............
if (isPolling()) {
// This is the workaround. Completing AsyncContext before cleaning up Atmosphere
resources
// seems to make this work everywhere.
//
AsyncContext asyncContext = (AsyncContext)
event
.getResource()
.getRequest()
.getAttribute("org.atmosphere.container.asyncContext");
if ( asyncContext != null ) {
asyncContext.complete();
}
event.getResource().resume();
} else {
postMessages();
}
}
..............
{code}
I am attaching a very simple WAR file that demonstrates the problem clearly. The demo app
does not use Richfaces, b/c I wanted to remove all unnecessary complexity. Instead I
created a couple of simple classes that mimic the behavior of
_org.richfaces.webapp.PushHandlerFilter_ and
_org.richfaces.application.push.impl.RequestImpl_. In the demo app, _MeteorRequest =
RequestImpl_, which is where the fix needs to go.
Please note that according to the Atmosphere author, this problem is fixed in 2.1 branch.
Here's the discussion:
https://groups.google.com/forum/#!topic/atmosphere-framework/KCKlSmbMrRo