Simulating Heartbeat from non-Vaadin page to keep UI alive

Hello ,
We have a hybrid application that is mostly in Vaadin with a few complex UI pages that are non-Vaadin using Kendo UI toolkit. The concern is if a user spends too much time on the non-Vaadin page the Vaadin UI will timeout after missing too many heartbeats.

Is there an easy way we can keep the Vaadin UI alive by simulating a heartbeat, i.e.

POST /ui/HEARTBEAT/?v-uiId=1 HTTP/1.1

Somehow I would need a way to determing the uiId which I’m guessing I should be able to pull out of the HttpSession somehow. The Vaadin UI lives in the same servlet context so it’s probably feasible just not sure how to go about it yet.

Any adivce?

Thanks

Here’s what I came up with:

Java Side (part of REST API call):

public class VaadinUILocator {

  public Set<UI> findUIs(final HttpServletRequest request) {
    final ImmutableSet.Builder<UI> uis = ImmutableSet.builder();
    final HttpSession session = request.getSession(false);
    if (session != null) {
      for (String attributeName : Collections.list(session.getAttributeNames())) {
        if (session.getAttribute(attributeName) instanceof VaadinSession) {
          final VaadinSession vaadinSession = (VaadinSession) session.getAttribute(attributeName);
          for (UI ui : vaadinSession.getUIs()) {
            uis.add(ui);
          }
        }
      }
    }
    return uis.build();
  }

  public Map<Integer, Map<String, Object>> toUIIdMap(final Set<UI> uis) {
    final ImmutableMap.Builder<Integer, Map<String, Object>> mapBuilder = ImmutableMap.builder();
    for (UI ui : uis) {
      final ImmutableMap.Builder<String, Object> uiBuilder = ImmutableMap.builder();
      uiBuilder.put("lastHeartbeatTimestamp", new DateTime(ui.getLastHeartbeatTimestamp()));
      mapBuilder.put(ui.getUIId(), uiBuilder.build());
    }

    return mapBuilder.build();
  }

}

Javascript side:

self.startHeartbeat = function(vaadinUIs) {
  self.heartbeat = $interval(function() {
  $log.log('Vaadin Heartbeat');
  $log.log(vaadinUIs);

  for(var k in vaadinUIs) {
    $http.post('/app/ui/HEARTBEAT/?v-uiId=' + k);
  }
  }, 5000);
};

Hi Kirk,

You probably realized this but I’d just like to note that this will also keep possible closed UIs alive for a bit longer - this might not matter to you, but still. Also, the attribute name of the VaadinSession is
com.vaadin.server.VaadinSession.
- this is not exactly public API but it’s unlikely to change any time soon :slight_smile:

Thanks Johannes.

Yeah the first version I wrote was looking it up by attribute name but then I realized I could scan for attributes by type so I made it a little more robust. I realize I’ll have to keep an eye out on any fundamental changes but hopefully this will keep us going for awhile. Vaadin may want to provide explicit support for the scenario I outlined above.