vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
609 stars 167 forks source link

Resync UI after returning to previous page. #7774

Open moryakovdv opened 4 years ago

moryakovdv commented 4 years ago

Hello. Faced some strange behavior with Vaadin 14. Vaadin-CDI application provides downloading of PDF file (with Anchor component). After StreamResource was generated the InputStream is delivered to client and opened in browser. Then user returns to previous page using browser "back" button. After that browser shows "Server connection lost. Trying to reconnect". In console I can see Vaadin warning:

INFO com.vaadin.flow.server.communication.ServerRpcHandler - Ignoring old duplicate message from the client. Expected: 11, got: 10 2020-03-10 10:13:10,133[ISO8601] [default task-2] DEBUG com.vaadin.flow.server.communication.UidlWriter - Creating response to client 2020-03-10 10:13:10,442[ISO8601] [default task-2] WARN com.vaadin.flow.server.communication.ServerRpcHandler - Resynchronizing UI by client's request. Under normal operations this should not happen and may indicate a bug in Vaadin platform. If you see this message regularly please open a bug report at https://github.com/vaadin/flow/issues 2020-03-10 10:13:10,444[ISO8601] [default task-2] DEBUG com.vaadin.flow.server.communication.UidlWriter - Creating response to client 2020-03-10 10:13:10,720[ISO8601] [default task-2] DEBUG com.vaadin.flow.server.communication.PushHandler - New push connection for resource 7529e3f2-04ce-4bb5-8865-830649207e3d with transport WEBSOCKET

After this my application does not respond properly. Seems like new VaadinSession was started and @VaadinSessionScoped objects were disposed or something of that kind.

I would find a workaround with "download" property of my Anchor, that allows all browsers to open download dialog. But in Safari under Ipad it doesn't work (there is no way to download pdf document except open it). My customer needs Safari on Ipad.

Hope to see any comments on this.

-- Best regards, Dmitry

pleku commented 4 years ago

Hi @moryakovdv . It does seem something is going wrong.

Can you please use https://github.com/vaadin/skeleton-starter-flow-cdi to create a minimal example to reproduce the issue ? It would help us a lot to get started in investigating this.

Also it is preferred to report the exact versions that you are using, like 14.1.18 or such, not just the major release.

moryakovdv commented 4 years ago

Hi,@pleku. Thanks for the response. Currently I use 14.1.17 vaadin.version I'll try to reproduce the issue in test project.

TatuLund commented 4 years ago

This could be related to https://github.com/vaadin/flow/issues/7553

moryakovdv commented 4 years ago

Hello. Sorry for the delay. Please, find attached zip file with sample project (using Vaadin 14.1.17 bom).

skeleton-starter-flow-cdi.zip

At a glance @SessionScoped, @VaadinSessionScoped objects are doing well during navigation.

But I still have issues in Safari browser on iPad Pro (iOS 13.3.1). Steps to reproduce:

  1. Load the project
  2. Press download button - the test pdf document should be shown in preview
  3. Navigate back to main view
  4. Safari shows "Server connection lost, trying to reconnect" and also "Trying to start a new request while another is active"
  5. Check the console for messages like:

15:49:35,601 INFO [com.vaadin.flow.server.communication.ServerRpcHandler] (default task-4) Ignoring old duplicate message from the client. Expected: 3, got: 2 15:49:45,679 WARN [com.vaadin.flow.server.communication.ServerRpcHandler] (default task-4) Resynchronizing UI by client's request. Under normal operations this should not happen and may indicate a bug in Vaadin platform. If you see this message regularly please open a bug report at https://github.com/vaadin/flow/issues

In main project, where I have @Push enabled to refresh grids, I can see more detailed messages like:

2020-03-16 16:16:08,415[ISO8601] [default I/O-13] DEBUG com.vaadin.flow.server.communication.PushHandler - Connection unexpectedly closed for resource 7e2d8b2c-ba44-4778-b528-e4ed641e8aab with transport WEBSOCKET 2020-03-16 16:16:15,733[ISO8601] [default task-6] INFO com.vaadin.flow.server.communication.ServerRpcHandler - Ignoring old duplicate message from the client. Expected: 17, got: 16 2020-03-16 16:16:15,733[ISO8601] [default task-6] DEBUG com.vaadin.flow.server.communication.UidlWriter - Creating response to client 2020-03-16 16:16:15,816[ISO8601] [default task-6] WARN com.vaadin.flow.server.communication.ServerRpcHandler - Resynchronizing UI by client's request. Under normal operations this should not happen and may indicate a bug in Vaadin platform. If you see this message regularly please open a bug report at https://github.com/vaadin/flow/issues 2020-03-16 16:16:15,817[ISO8601] [default task-6] DEBUG com.vaadin.flow.server.communication.UidlWriter - Creating response to client 2020-03-16 16:16:15,877[ISO8601] [default task-6] DEBUG com.vaadin.flow.server.communication.PushHandler - New push connection for resource 7e2d8b2c-ba44-4778-b528-e4ed641e8aab with transport WEBSOCKET

  1. After that if you try to download pdf again you may (occasionally) get 404 error while navigating to .../VAADIN/dynamic/resource/1/...../test.pdf.

Tried to initialize components both in @PostConstruct method and onAttach receiver. Same issues.

All of this seems to be broken only under Safari. FF&Chrome are doing well when return on the previous page.

-- Regards, Dmitry

johannest commented 8 months ago

My customer was able to reproduce this issue with very simple code:

StreamResource excelFile = createResourceExcel();
Button downloadExcelButton = new Button();
downloadExcelButton.setText("download");
Anchor downloadExcel = new Anchor(excelFile, "");
downloadExcel.add(downloadExcelButton);
add(downloadExcel);

I tried it in my dev with V24.3.3 and following code and it reproduces consistently with latest Safari

private StreamResource createResourceExcel() {
        StreamResource resource = new StreamResource("image.xls",
                () -> getImageInputStream("foo"));
        return resource;
    }

    private InputStream getImageInputStream(String name) {
        String svg = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
                     + "<svg xmlns='http://www.w3.org/2000/svg' "
                     + "xmlns:xlink='http://www.w3.org/1999/xlink'>"
                     + "<rect x='10' y='10' height='100' width='100' "
                     + "style=' fill: #90C3D4'/><text x='30' y='30' fill='red'>"
                     + name + "</text>" + "</svg>";
        return new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
    }

Server log:

 Resynchronizing UI by client's request. A network message was lost before reaching the client and the client is reloading the full UI state. This typically happens because of a bad network connection with packet loss or because of some part of the network infrastructure (load balancer, proxy) terminating a push (websocket or long-polling) connection. If you are using push with a proxy, make sure the push timeout is set to be smaller than the proxy connection timeout

Browser's console:

[Log] Sending xhr message to server: {"csrfToken":"7613e76e-e41b-4650-9ebc-0f5327123f53","rpc":[{"type":"event","node":5,"event":"click","data":{"event.shiftKey":false,"event.metaKey":false,"event.detail":1,"event.ctrlKey":false,"event.clientX":332,"event.clientY":176,"event.altKey":false,"event.button":0,"event.screenY":272,"event.screenX":-1436}}],"syncId":3,"clientId":3} (FlowClient.js, line 207)
[Debug] Tue Jan 30 2024 15:27:39 GMT+0200 (Eastern European Standard Time) Atmosphere: beforeunload event (vaadinPush.js, line 3323)
[Warning] Server returned 0 for xhr (FlowClient.js, line 208)
[Warning] Reconnecting because of XHR failure (FlowClient.js, line 208)
[Log] Reconnect attempt 1 for XHR (FlowClient.js, line 207)
[Log] Re-sending last message to the server... (FlowClient.js, line 1015)
[Error] XMLHttpRequest cannot load http://localhost:8080/?v-r=uidl&v-uiId=1 due to access control checks.
    RB (FlowClient.js:960:139)
    ut (FlowClient.js:970)
    Wr (FlowClient.js:620)
    Yp (FlowClient.js:1015:249)
    nq (FlowClient.js:877)
    _p (FlowClient.js:1022:412)
    qq (FlowClient.js:944:210)
    Bt (FlowClient.js:1052:22593)
    TB (FlowClient.js:1052:35966)
    (anonymous function) (FlowClient.js:627)
    Hb (FlowClient.js:918)
[Log] Sending xhr message to server: {"csrfToken":"7613e76e-e41b-4650-9ebc-0f5327123f53","rpc":[{"type":"event","node":5,"event":"click","data":{"event.shiftKey":false,"event.metaKey":false,"event.detail":1,"event.ctrlKey":false,"event.clientX":332,"event.clientY":176,"event.altKey":false,"event.button":0,"event.screenY":272,"event.screenX":-1436}}],"syncId":3,"clientId":3} (FlowClient.js, line 207)
[Warning] Server returned 0 for xhr (FlowClient.js, line 208)

However, there is a simple workaround: downloadExcel.getElement().setAttribute("download", true); which seems to fix the issue.