Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

package will not work when Chrome local cache is in place #6

Open
lz100 opened this issue Nov 27, 2020 · 11 comments
Open

package will not work when Chrome local cache is in place #6

lz100 opened this issue Nov 27, 2020 · 11 comments

Comments

@lz100
Copy link

lz100 commented Nov 27, 2020

A simple example:

  1. Run the basic shinydisconnect example locally on Chrome, you should see a tab opens.
  2. Stop the server from R or Rstudio.
  3. Directly close the shiny tab on Chrome, do not hit refresh or F5.
  4. Ctrl + shift + t to resume the previous tab.

or:

  1. open https://daattali.com/shiny/shinydisconnect-demo/
  2. archive this app from shinyapps.io
  3. and 4. same as above

You will find the app is back, All UI is clickable. As expected, for those need the backend will not work, but still, users can play around which is not ideal. In the original Shiny, this is prevented by the shiny-disconnected-overlay. Sine you disabled it #shiny-disconnected-overlay { display: none !important; }, the protection is gone.

Here is what I did:

  1. bring the #shiny-disconnected-overlay back but one layer below 99997, so the #ss-connect-dialog is till on top.
  2. Add a 3s (you can change it to any time) function on the app start to check if the server is connected, check every second. If yes, this function stops and will get deleted; if timeout, display the "Cannot connect to the server" message.
  3. change the text from ss-connect-dialog to .shiny-discon::before and .shiny-discon-noserver. I toggle the class later in js.
  4. All js code is placed in a file instead of in shiny UI.
  5. the way you write your demo makes the connection checking function run undesirably. Most people use the disconnetMessage on the UI side, just like your other examples which are fine, my checker will be deleted after first 3s. In your, demo, you insert this to DOM and immediately stops the sever. So the script is inserted at the same time as the server closes. So my function runs after the sever is ended. So, it will first display your error message but 3s later change to "Cannot connect to the server". To fix this, I fake the socket after shinyapps.js delete it:
      $(document).on('shiny:disconnected', function(event){
        setTimeout(function() {
          Shiny.shinyapp.$socket = 'fake';
        }, 1000);
      });

I tried locally and deployed it to my account with no problem, fixed this issue. Please try it out #5 .

@daattali
Copy link
Owner

You're right, I haven't thought about this issue. Thanks for the report

@daattali
Copy link
Owner

daattali commented Dec 4, 2020

I just tested the changes for the first time. I followed the steps you outlined:

  1. Run the following app

      library(shiny)
      shinyApp(
        ui = fluidPage(
          disconnectMessage(),
          actionButton("disconnect", "Disconnect the app")
        ),
        server = function(input, output, session) {
          observeEvent(input$disconnect, {
            session$close()
          })
        }
      )
    
  2. Stop the app in RStudio

  3. Now the app shows a black overlay with the shinydisconnect message

  4. Close the browser tab

  5. Re-open the browser tab with ctrl+shift+t

I expected to now see the same overlay+message. Even after waiting 10 seconds, the screen is still white with no message. Are you seeing a different behaviour?

@lz100
Copy link
Author

lz100 commented Dec 4, 2020

I normally do
2. close the tab
3. stop app in Rstudio
4. ctrl+shift+t
Your steps should also work, I tested with your steps and I do see the message.
image.

  • Did you see any message in the browser console beside the net::ERR_CONNECTION_REFUSED error?
  • Did you install the changed version from my fork? remotes::install_github("lz100/shinydisconnect")

Chrome Version 87.0, shiny 1.5.0

@daattali
Copy link
Owner

daattali commented Dec 6, 2020

Yes I installed lz100/shinydisconnect and I tried Chrome (version 86) and firefox, I'm still not seeing the disconnect message on re-connection. shiny is indeed version 1.5 CRAN release

I did notice now that the cursor becomes "not-allowed" when I re-open the tab so something is happening, and I also see a javascript error. See the GIF screencast beloe.

shinydisconnect

@daattali
Copy link
Owner

daattali commented Dec 6, 2020

Do you have your version deployed anywhere so I can test other browsers on other devices?

@lz100
Copy link
Author

lz100 commented Dec 8, 2020

I found the problem. I guess you are using a Windows machine. This is Windows specific. I am using a Linux machine and it worked well. The shiny server deployment is also Linux so I couldn't replicate this. I tried on my Windows machine today and found it is because shiny js behaves differently on Win and Linux.

It turns out when the Shiny js runs on Win, it first setup the socket value in Shiny.shinyapp.$socket. If the socket is not conneted, change the socket to null. On Linux, it is null on start and when the socket is connected, set it to the value. If you log the Shiny.shinyapp.$socket, when you resume a tab, on Windows it is "ws://127.0.0.1:xxxx/websocket/" but on Linux it is null.

So, my original script detects if there is a socket been set up. It finds the Shiny.shinyapp.$socket !== null is true on Windows, then stops the loop. The Shiny js updating mechanism on Win gives my function a false positive. My function is then stopped and will not check again after the socket is updated to null.

solution: This time I check the state Shiny.shinyapp.$socket.readyState === 1. It is always 0 if the server is not connected, no matter Windows or Linux. Let me know if this fixes the issue,

@daattali
Copy link
Owner

daattali commented Dec 17, 2020

Thanks for looking into this and explaining. It does work now, but I also get a javascript error:

shinydisconnect.js:26 Uncaught TypeError: Cannot read property 'readyState' of null
    at shinydisconnect.js:26

It's referring to Shiny.shinyapp.$socket which is null

Should it check also for null?

@daattali
Copy link
Owner

I noticed an issue today with this PR. I was developing a shiny app that was using shinydisconnect, and my version of shinydisconnect is the one from this PR.

I opened the app in a browser and killed the R session almost immediately. The shiny app initially showed a message "An error occured. Please refresh the page and tried again" and after 3 seconds it changed the message to "Cannot connect to the server".

I suppose the solution could be to check if a message is already shown to the user

@lz100
Copy link
Author

lz100 commented Dec 19, 2020

  • add a Shiny.shinyapp.$socket != null check
  • add a global var disconDisplayed flag to prevent the second message to be displayed.
  • remove 'fake' socket in demo, since we have disconDisplayed flag, no longer needed.
  • version up in DESCRIPTION.

Let me know if these fix the problems

@daattalitest
Copy link

I didn't bookmark the notification from this repo so I forgot about it. I'm making this comment so that I'll get a notification on my main account and be able to "bookmark" it :)

@lz100
Copy link
Author

lz100 commented May 31, 2021

No problem. Thanks for reminding me on this too. I almost forget what changes I made. I remember I made another commit to fix things as you suggested, but maybe you can take a look at what we have so far and tell me if other things need to be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants