Search in sources :

Example 1 with DomApi

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));
}
Also used : DomApi(com.vaadin.client.flow.dom.DomApi) JsonObject(elemental.json.JsonObject)

Aggregations

DomApi (com.vaadin.client.flow.dom.DomApi)1 JsonObject (elemental.json.JsonObject)1