Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Compensate Server-Client delay
I'm having a project/Application (still Vaadin 6.8.13 unfortunately because of Browser compatibility reasons. with Refresher Add-On for polling) in which i display a Clock. Currently this clock works by updating a Label every minute from a Server side thread. This works and the time on the client is actually accurate. What really is buggying me is the fact that I have so much traffic for a simple clock for which i had to add a seperate Refresher and set it to 1 minute (The Refresher isn't just for the Clock but without it i could set it to something around 15 minutes).
That's why i decided to create a custom component which in essence does this:
When the constructor is called i get the current time on the server (using Calendar.getInstance()) and save hours, minutes, seconds, milliseconds to variables which are added as attributes to the PaintTarget.
After that i call requestRepaint which sends the information to the client-side.
On the client i retrieve the attributes and start a Timer which updates a div every second and increases hours-, minutes-, seconds-variables in the client-side class.
This in theory works. The only problem is. There is a notable around 3 seconds delay which probably comes from the time the attributes reach the client or/and the time the attributes are processed and included in the div.
My question is: Is there any way i could compensate this delay without causing a server->client call every x seconds/minutes?
Thanks in advance.
PS: It is also important that i use the current Time on the Server and not the client.
What do you mean by the 3s delay? A difference between the real time and the time shown on the UI?
I would guess that the first request (in which you get the initial time) takes a while because the whole UI is updated in it, not just the time. Thus, scheduling a single sync request a few seconds later might result in a smaller offset.
On the other hand, if the delay comes from the network, you could time the round trip of the request and divide the time by two to correct the offset. If other Vaadin overhead is too big or unpredictable and distorts the results of that approach, consider adding a second servlet in the application that does nothing but serve the time as a string, in which case network latency should be the only factor you need to correct for. You might still want to resync e.g. every 15 min or every hour.
Yes pretty much. From the time the Component gets initialised on the server until the Timer gets initialised it seems like, in my test case, 3 seconds pass. So for example when on the server is at 33 seconds the client is at 30.
I'm wondering how one could time the round trip of the request? Get the time, make a server-client request by updating some variable and call requestrepaint (is this even necessary? am more used to creating components in V7 so i don't know...) and then make a client->server request immediately in updateFromUIDL and then get the time on the server again and see the difference? Or is there a better way?
I will try out your suggestion as soon as i find the time to do so.
Thank you very much fory your suggestions so far.
Multiple round-trips can give more accurate data, but I'd say in Vaadin 6, it should be sufficient to start timing, update a variable from the client (with immediate=true) and wait for an updateFromUIDL for the widget (containing the server time) to stop the client side timing and check the round trip time. Other updates may get piggy-backed on the same one, but it is unlikely if you do all this with a timer 2-3s later rather than in the initial rendering.
So a lot of my delay was just caused by my own stupidity:
1 second comes from me getting the time, then waiting until the next full second and then starting the 1 second timer which displays the time and not adding a second before doing so.
Another second delay comes from me executing the 1 sec timer by only calling timer.scheduleRepeating(1000) without realising that it will take one full second until it's getting executed the first time.
The remaining delay though i was able to rid of by first getting the time a few seconds after the widget was initialised and two by meassuring the time it takes for a request to make a server roundtrip and then subtracting half of that from the time.
I'm also going to implement a synchronization after x minutes as you said although but it is already quite stable and accurate.
Thank you again for your suggestions/thoughts on that topic.