Coder Social home page Coder Social logo

Comments (10)

ptaoussanis avatar ptaoussanis commented on August 22, 2024

Hi Bob,

Apologies for the huge delay getting back to you, was on vacation + trying to avoid non-critical distractions while the opportunity presented :-)

I'm really very happy with Sente, thanks. Release 0.13.0 made a huge difference to my application. I upgraded to 0.14.1 today, everything still works so no worries there :-)

Oh great, happy to hear that!

If I re-draw the page in the browser I'll get an chsk/uidport-close followed by a chsk/uidport-open with the same session-id. It's almost as though it's dropping then re-establishing the connection. If this is a reconnection then I definitely don't want to clean up after the close.

Hmm, what do you mean exactly when you say "redraw"? A browser page refresh will clear all connections, so a close/open would be expected.

What do these events actually mean at Sente's level and at the application level? When should they be used? When should they not be used? Your thoughts on this would be greatly appreciated.

You should be okay to use them as you described (i.e. for cleanup, etc.).

  • chsk/uidport-open triggers when a particular user connects and wasn't previously connected[1].
  • chsk/uidport-close triggers when a particular user disconnects and was previously connected[2].

Open+close notifications should both be instantaneous for WebSocket connections. There'll be a couple second lag for Ajax close notifications.

Does that help / make sense? Are you seeing the expected behaviour?

[1] E.g. with a different device/client/etc.
[2] With any device/client/etc.

Cheers! :-)

from sente.

hutch avatar hutch commented on August 22, 2024

Thanks.

What I meant by 'redraw' was 'refresh' or 'reload' or...

The 'surprise' was not that I got a close and open (I expected that) but that the session id was re-used. I'm not sure how this is happening. I've got this bit of code (paraphrased) that is called whenever the page is reloaded

(defn establish-uuid [req]
  (let [session-uid (-> req :session :uuid)]
    (if session-uid
      session-uid
      (some-complex-stuff))))

Is it possible that the request still has the old session uuid in it? Am I supposed to kill the old session? Maybe something entirely different is going on.

Everything works if I reuse that session, so I'm not even sure if there's a problem here. But since I've got my resources tied to the session, I just can't make use of the chsk/uidport-close and chsk/uidport-open events to clean up. I could make use of them if the session was actually clobbered when the chsk/uidport-close event happens (can you do that from the ws connection (I'm thinking not)?).

I don't think I'm explaining myself well. Sorry.

from sente.

ptaoussanis avatar ptaoussanis commented on August 22, 2024

Hey Bob, so the behaviour you should be expecting on browser refresh goes like this:

  • chsk/uidport-close will trigger (because the browser will release all connections).
  • The browser will re-request the same page from scratch (like the initial load), but with the preexisting session (a browser refresh does not clear sessions[1]).
  • chsk/uidport-open will trigger as your ClojureScript executes and Sente reconnects.

[1] Just clarifying to be safe, feel free to ignore if you already know this: A big point + benefit of sessions is that they do not clear with page reloads. They survive [usually at least] an entire browsing "session", including the opening+closing of multiple browser windows. Amazon.com won't forget who you are because of a page reload or because you've changed the URL (for e.g. when stepping through the checkout process). To get Amazon.com to forget your identity (session), you'd need to sign out (deletes your session), change browsers entirely, or ask your browser to delete your sessions.

I could make use of them if the session was actually clobbered when the chsk/uidport-close event happens (can you do that from the ws connection (I'm thinking not)?).

A WebSocket session comes from the initial HTTP handshake which requests an upgrade to a WebSocket connection. If you wanted to clobber a user's session on chsk/uidport-close you could do that server-side if you have an index of user-id->session-id (session-id as per your session store). This way you can instruct your session store to clobber the relevant session-id when a chsk/uidport-close event is detected. Does that make sense?

This'll depend on what behaviour you're looking for exactly, but I'd suggest that you probably don't want to clobber / clean-up sessions on chsk/uidport-close since that'd sort of defeat the purpose of having a session in the first place (having a user identity that persists across windows + reloads).

For most applications you'll want to clear your session only on an explicit "sign out" request.

Does that make sense? It's very possible I've misunderstood your question/goals so just point me in the right direction if I have :-)

Cheers!

from sente.

hutch avatar hutch commented on August 22, 2024

Hi,

Your three bullet points describe what I expected and what I'm seeing. So this is good (and it's why I said I'm not sure there's a problem -- in which case it's just (my) confusion).

We've got a bunch of browsers that more or less do the same thing these days, websocket connections, sessions/cookies, http-kit, Ring, Compojure, Sente, ClojureScript, React, Reagent, Google Closure, and my software which is layering my user management over Sente's user management. And unbelievably everything is working rather nicely :-)

So, let's try to simplify this: What are chsk/uidport-close and chsk/uidport-open telling me, and given that the HTTP session/cookie isn't changing, what can I do with that information?

Whew. Sigh.

Cheers,
Bob

from sente.

ptaoussanis avatar ptaoussanis commented on August 22, 2024

[...] And unbelievably everything is working rather nicely :-)

Oh, I know the feeling. Lots of good things about modern web dev; simplicity not being one :-)

So, let's try to simplify this: What are chsk/uidport-close and chsk/uidport-open telling me, and given that the HTTP session/cookie isn't changing, what can I do with that information?

Good idea.

  • chsk/uidport-close - Tells your server that a user[1] appears to have disconnected (e.g. switched off) all his devices.
  • chsk/uidport-open - Tells your server that a previously disconnected user[1] has just connected at least one device.

[1] Remember that users are uniquely identified by their session user-id.

An example use case would be a chat room displaying a live "Who's online now' list. Each time the server gets a open/close event, it can relay that info to all connected clients to maintain the list.

If users actually log in with a particular user-id, you'll probably also have a log out link to clear their session + do any other cleanup work your application may need.

Does that help? :-)

from sente.

hutch avatar hutch commented on August 22, 2024

Okay, becoming clearer...

I've got my own user management layer that sits on top of Sente, so, for me, there's a 1-1 relationship between Sente-connection and Sente-user. Which means that I'm using Sente in a relatively simple way.

I'm seeing a very rapid close-open sequence of events (probably due to the fact that I'm testing and so reloading resources a lot) but this is happening.

In your chat room example, might you not want to wait a moment before deciding that the user actually closed the connection? If one of these rapid close-open sequences happens then there could be a lot of unnecessary notifications flying around. This is roughly where my issue came from, I was reacting immediately to the close and cleaning up after the session, when I should maybe have waited a brief time to allow the open if it was going to happen.

It's not been my experience that users reliably sign themselves out :-) So some kind of sweap is needed to cleanup resources. Using Sente's close event that isn't followed by an open event could be a handy trigger. So I think all I have to do is add the brief delay.

Right?

from sente.

ptaoussanis avatar ptaoussanis commented on August 22, 2024

In your chat room example, might you not want to wait a moment before deciding that the user actually closed the connection? If one of these rapid close-open sequences happens then there could be a lot of unnecessary notifications flying around.

Sounds good to me! There's already a 5 second close delay for Ajax conns (for technical reasons); would be simple to introduce the same thing for WebSocket conns to cut down on noise. Nice idea.

So I think all I have to do is add the brief delay. Right?

Sure, that'd be doable on your end with (say) a core.async cleanup timeout that you start on disconnect (close event) and cancel on connect (open event). Then you get something like: cleanup automatically 2 minutes (or whatever) after last disconnect that wasn't followed by another connect.

Anyway, it'd definitely make sense for Sente to implement its own (at least small) delay - so I'll get back to you on that!

from sente.

hutch avatar hutch commented on August 22, 2024

Great, thanks!

from sente.

ptaoussanis avatar ptaoussanis commented on August 22, 2024

Closing this issue, will be on the delayed port close message today. Cheers! :-)

from sente.

ptaoussanis avatar ptaoussanis commented on August 22, 2024

Okay, included in v0.15.0 which I'll be pushing soon.

from sente.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.