use of com.vaadin.client.flow.dom.DomApi in project flow by vaadin.
the class MessageHandler method handleJSON.
protected void handleJSON(final ValueMap valueMap) {
final int serverId = getServerId(valueMap);
if (isResynchronize(valueMap) && !isNextExpectedMessage(serverId)) {
// Resynchronize request. We must remove any old pending
// messages and ensure this is handled next. Otherwise we
// would keep waiting for an older message forever (if this
// is triggered by forceHandleMessage)
Console.log("Received resync message with id " + serverId + " while waiting for " + getExpectedServerId());
lastSeenServerSyncId = serverId - 1;
removeOldPendingMessages();
}
boolean locked = !responseHandlingLocks.isEmpty();
if (locked || !isNextExpectedMessage(serverId)) {
if (locked) {
// Some component is doing something that can't be interrupted
// (e.g. animation that should be smooth). Enqueue the UIDL
// message for later processing.
Console.log("Postponing UIDL handling due to lock...");
} else {
// Unexpected server id
if (serverId <= lastSeenServerSyncId) {
// Why is the server re-sending an old package? Ignore it
Console.warn("Received message with server id " + serverId + " but have already seen " + lastSeenServerSyncId + ". Ignoring it");
endRequestIfResponse(valueMap);
return;
}
// We are waiting for an earlier message...
Console.log("Received message with server id " + serverId + " but expected " + getExpectedServerId() + ". Postponing handling until the missing message(s) have been received");
}
pendingUIDLMessages.push(new PendingUIDLMessage(valueMap));
if (!forceHandleMessage.isRunning()) {
int timeout = registry.getApplicationConfiguration().getMaxMessageSuspendTimeout();
forceHandleMessage.schedule(timeout);
}
return;
}
/**
* Should only prepare resync after the if (locked ||
* !isNextExpectedMessage(serverId)) {...} since
* stateTree.repareForResync() will remove the nodes, and if locked is
* true, it will return without handling the message, thus won't adding
* nodes back.
*
* This is related to https://github.com/vaadin/flow/issues/8699 It
* seems that the reason is that `connectClient` is removed from the
* rootNode(<body> element) during a resync and not added back.
*/
if (isResynchronize(valueMap)) {
// Unregister all nodes and rebuild the state tree
registry.getStateTree().prepareForResync();
}
double start = Duration.currentTimeMillis();
/*
* Lock response handling to avoid a situation where something pushed
* from the server gets processed while waiting for e.g. lazily loaded
* connectors that are needed for processing the current message.
*/
final Object lock = new Object();
suspendReponseHandling(lock);
Console.log("Handling message from server");
registry.getRequestResponseTracker().fireEvent(new ResponseHandlingStartedEvent());
// cause a resync (which must use the updated id)
if (valueMap.containsKey(ApplicationConstants.CLIENT_TO_SERVER_ID)) {
int serverNextExpected = valueMap.getInt(ApplicationConstants.CLIENT_TO_SERVER_ID);
registry.getMessageSender().setClientToServerMessageId(serverNextExpected, isResynchronize(valueMap));
}
if (serverId != -1) {
/*
* Use sync id unless explicitly set as undefined, as is done by
* e.g. critical server-side notifications
*/
lastSeenServerSyncId = serverId;
}
// Handle redirect
if (valueMap.containsKey("redirect")) {
String url = valueMap.getValueMap("redirect").getString("url");
Console.log("redirecting to " + url);
WidgetUtil.redirect(url);
return;
}
// Get security key
if (valueMap.containsKey(ApplicationConstants.UIDL_SECURITY_TOKEN_ID)) {
csrfToken = valueMap.getString(ApplicationConstants.UIDL_SECURITY_TOKEN_ID);
}
// Get push id if present
if (valueMap.containsKey(ApplicationConstants.UIDL_PUSH_ID)) {
pushId = valueMap.getString(ApplicationConstants.UIDL_PUSH_ID);
}
handleDependencies(valueMap.cast());
if (!initialMessageHandled) {
/*
* When handling the initial JSON message, dependencies are embedded
* in the HTML document instead of being injected by
* DependencyLoader. We must still explicitly wait for all HTML
* imports from the HTML document to be loaded. It's not necessary
* to explicitly wait for JavaScript dependencies since the browser
* already takes care of that for us.
*/
registry.getDependencyLoader().requireHtmlImportsReady();
}
/*
* Hook for e.g. TestBench to get details about server performance
*/
if (valueMap.containsKey("timings")) {
serverTimingInfo = valueMap.getValueMap("timings");
}
DependencyLoader.runWhenEagerDependenciesLoaded(DomApi::updateApiImplementation);
DependencyLoader.runWhenEagerDependenciesLoaded(() -> processMessage(valueMap, lock, start));
}
Aggregations