I have migrated an application from Struts to GWT because in Struts we
had a Loss of Focus everytime a page refreshes or rather reloads. My
application needs to update itself every 5 seconds.
In IE v6.0 GWT implementation has addressed the problem of losing focus
but in Firefox v1.0.8 it is flickering everytime when data refreshing
takes place.
Further rendering of Widgets in IE and firefox is not exactly same with
latter showing some unexpected behaviour. Though issues with few
Widgets have been addressed in latest release but still there are many
more to be addressed.
Also, few refresh calls in IE v6.0 are running afoul and we are getting
SocketTimeoutException on server side while the same code is running
without any such behaviour in Firefox v1.0.8.
Any comments/insight on this are highly appreciated.
Thanks,
Rahul
I am providing you the sample code that is I have coded for EntryPoint
class in GWT and which is having different behaviour for two browsers:
public class GetDataEntryPoint implements EntryPoint
{
private boolean myHasResponded = false;
private long myLastCallTime = 0;
private Timer myTimer = null;
private static ServiceAsync serviceAsync = (ServiceAsync)
GWT.create(Service.class);
public void onModuleLoad()
{
VerticalPanel inputPanel = new VerticalPanel();
// HERE GOES CODE TO CREATE WIDGETS FOR DISPLAY
// AND SET THEM IN inputPanel.
RootPanel.get().add(inputPanel);
// GET DATA FROM RPC CALL AND PUT IN WIDGETS THAT
// ARE SET IN inputPanel ABOVE.
fetchData();
// REFRESH DATA.
refreshData();
}
private void fetchData()
{
myLastCallTime = System.currentTimeMillis();
serviceAsync.getXYZ(param1, param2, new AsyncCallback() {
public void OnSuccess(Object result)
{
myHasResponded = true;
// CODE FOR PARSING RESULT, WHICH IS DATA
// FETCHED FROM SERVER IN THE FORM OF
// Collection. THIS Collection IS AN ArrayList AND
// CONTAINS OTHER ArrayList(s) WHICH
// FINALLY HAS String DATA AT LOWEST LEVEL.
// ITERATING OVER Collection OBTAINED TO FILL WIDGETS.
}
public void onFailure(Throwable caught)
{
myHasResponded = true;
}
});
}
private void refreshData()
{
myTimer = new Timer() {
public void run()
{
long currentTime = System.currentTimeMillis();
if (myHasResponded) {
myHasResponded = false;
fetchData();
}
// CALLING FALLBACK MECHANISM IF NO ACTIVITY IS
// REGISTERED FOR LAST 30 SECONDS.
else if ((currentTime - myLastCallTime) >30000) {
callFallBack();
}
}
};
// SCHEDULING THE TIMER TO RUN ONCE IN 5 SECONDS.
myTimer.scheduleRepeating(5000);
}
private void callFallBack()
{
myTimer.cancel();
myLastCallTime = System.currentTimeMillis();
refreshData();
fetchData();
}
}
I think this code is sufficient to understand the jist of what I am
doing to display data. This code does not have problem of focus loss in
IE v6.0 while in Firefox v1.0.8 this code is flickering every time it
refreshes data.
Also, the above code is deployed on jboss server. As far as server side
is concerned, in Firefox v1.0.8 it is running fine but when this page
is accessed on IE v6.0 one in hundred calls is running afoul and
throwing following exception at server side:
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at
org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:747)
at
org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:777)
at
org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:115)
at
org.apache.coyote.http11.InternalInputBuffer.doRead(InternalInputBuffer.java:712)
at org.apache.coyote.Request.doRead(Request.java:429)
at
org.apache.coyote.tomcat5.InputBuffer.realReadBytes(InputBuffer.java:290)
at
org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:374)
at
org.apache.coyote.tomcat5.InputBuffer.read(InputBuffer.java:305)
at
org.apache.coyote.tomcat5.CoyoteInputStream.read(CoyoteInputStream.java:179)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.readPayloadAsUtf8(RemoteServiceServlet.java:530)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:142)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237).........
Further, there are few widgets which have different behaviour in two
browsers and one common problem is related to not proper working of
setWordWrap() function.
Thanks for your time.
Rahul.
// SCHEDULING THE TIMER TO RUN ONCE IN 5 SECONDS.
myTimer.scheduleRepeating(5000);
it should be
myTimer.schedule(5000);
I would guess that the possibility occurs that the server is delayed
and still processing a request while a new request is fired. It would
be better to start a new timer when the respnse comes back ( in both
the success/failure methods). That way the client code would fire a new
requeset at most once every 5 seconds.
It is scheduled to fire each and every 5 seconds but it will not send a
new request until a response for previous request has come OR there is
no activity for last 30 seconds.
In latter case it will cancel the previous timer and fires a new timer
to repeat the same story.
Thanks,
Rahul
org.apache.coyote.http11.InternalInputBuffer.fill (InternalInputBuffer.java:747)
at
org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:777)
at
org.apache.coyote.http11.filters.IdentityInputFilter.doRead (IdentityInputFilter.java:115)
at
org.apache.coyote.http11.InternalInputBuffer.doRead(InternalInputBuffer.java:712)
at org.apache.coyote.Request.doRead(Request.java:429)
at
org.apache.coyote.tomcat5.InputBuffer.realReadBytes (InputBuffer.java:290)
at
org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:374)
at
org.apache.coyote.tomcat5.InputBuffer.read(InputBuffer.java:305)
at
org.apache.coyote.tomcat5.CoyoteInputStream.read (CoyoteInputStream.java:179)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.readPayloadAsUtf8(RemoteServiceServlet.java:530)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost (RemoteServiceServlet.java:142)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:237).........
Hi Dan,
org.apache.coyote.tomcat5.InputBuffer.read (InputBuffer.java:305)
at
org.apache.coyote.tomcat5.CoyoteInputStream.read (CoyoteInputStream.java:179)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.readPayloadAsUtf8(RemoteServiceServlet.java :530)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost (RemoteServiceServlet.java:142)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:810)
I thought of mentioning all the issues related to browser incompatibilities in same thread. Going forward I will put them under separate threads.
By flickering, I mean to say that every 5 second when there is a code refresh Firefox repaints the whole page which appears as if it is flickering, even if there is no change in display data. While in IE refreshing does not seems like it is repainting the page. Further, until and unless there is a change in content of display data IE does not seem to refresh it every 5 second (the refresh time set for page) while Firefox does. Let me know if this description is sufficient.
>> Regarding your IE socket timeout issue, it looks like you are not resetting myHasResponded correctly.Is there a better way to handle the scenario.
I think GWT should provide us with a handle for the request sent, so that we can invalidate the previous request in 30 seconds (as a part of failsafe strategy) before sending a new request. It will cover all the possible scenario of getting weird results. OR we should have a mechanism to set time-out for a RPC call - Something similar to what latest version of RequestHandler class have (setTimeoutMillis).
From our discussion, I think there are two ways of dealing with this situation of flickering,1) check if response data has changed and do the repainting of widget on that basis.
Could you make it more clear that why you want to set myHasResponded to false in callFallBack(), as anyway it is false then only it is coming inside callFallBack() .
7) Enter callFallBack() it will first cancel Timer in the hope that associated request will also die down. Now it will invoke refreshData() but since myHasResponded is still false its if block will not be executed and also it doesn't satisfy the condition of else-if block so even that will not be executed.
Hi Dan,
It was quite an insightful discussion, but we can only conclude that problem can be solved only when we have a mechanism to get decide fate of request sent.
I got your point of setting myHasResponded=false in callFallBack(), but then it is just our assumption that previous call will not return between setting myHasResponded=false in callFallBack() and the execution of subsequent statement. Practically, it can come up anytime and things may run afoul. But yeah setting myHasResponded=false at some important points will lower the probability of weird results.
Thanks for your time.
Rahul