Comments (10)
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.
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.
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.
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.
[...] 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.
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.
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.
Great, thanks!
from sente.
Closing this issue, will be on the delayed port close message today. Cheers! :-)
from sente.
Okay, included in v0.15.0
which I'll be pushing soon.
from sente.
Related Issues (20)
- Add support for additional client/server adapters
- Client-id is nil in version 1.17.0 HOT 3
- Issue with 1.18.0-RC1 Cljs build HOT 8
- After upgrading to 1.18 event :chsk/uidport-close desn't work HOT 7
- Some dead websocket connections are never cleaned up HOT 27
- Example project browser auto-start exception HOT 1
- Sente 1.19.0 Encore version can cause build issues with shadow-cljs HOT 2
- Logged secrets when :client-id is nil HOT 2
- Websocket failing to communicate after 20 seconds HOT 9
- Complete catalog of client-side events HOT 7
- Ping events subject to wrapping by `wrap-recv-evs`?
- The very first time HOT 4
- Connection was interrupted while the page was loading HOT 24
- Carrier-grade NAT may affect the stability of websocket connections HOT 4
- Trouble transferring large data with Sente
- Ring 1.11 adoption HOT 4
- Undertow adapter error in logs HOT 7
- Possible out-of-order delivery of server->client messages HOT 14
- nodejs: call to undefined addEventListener causing problems HOT 1
- Uberjar failure with direct-linking=true HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sente.