Comments (11)
Hi Bob, sorry for the delay getting back to you!
I have Sente working with my application. Things are looking very good. Well done!
Happy to hear it :-)
The basics are very straight forward, but you might want to move some of the information in issue 17 into the docs.
That's a good suggestion. Planning another revision to the docs (login/auth especially), just really short on time recently.
when you establish a chsk connection you have to know the uid that will be associated with it.
You only need to know whether some uid will be associated with it, the particular uid is irrelevant. This is for the client's make-channel-socket!
:has-uid?
arg.
This arg's only purpose is to instruct the client whether or not to try create a long-polling Ajax connection. If a user isn't logged in, that'd just be a wasted HTTP roundtrip.
Actually, am thinking of just dropping this option since it seems to be causing confusion. One unnecessary HTTP roundtrip wouldn't be the end of the world.
I'm building an application where I'd like to open a chsk channel to an anonymous user
Sure, that's no problem. You'll have all usual capabilities except for server>user
async push (which needs a uid).
One way that I can think of to do this is to create a new channel whenever the user state changes
Your strategy will have to depend on what you mean here by "state changes". As a quick recap:
- Sente user-ids correspond 1-to-1 with a client's session. This is necessary for security.
- User-ids are necessary only for
server>user
async push. - The client's
make-channel-socket!
call will connect to the server using whatever session the server has at the time of the call. Again, for security reasons there's no way of getting around this. - User-ids may but do not have to correspond 1-to-1 with your application's concept of "signed in" (I'll expand on this in a moment).
So if you want an updated session for a user (notably after a user-id has been assigned during login), you will need to recreate your socket with make-channel-socket!
.
You could do something like
(def sente (atom (make-channel-socket! <...>))) ; {:keys [chsk ch-recv send-fn]}
and reset that on changes.
Things that you have some leeway with:
- How+when you update your session. This could be done with a page reload, an Ajax request, etc.
- Your app's concept of "signed in" / "signed out". It may be possible, for example, to always assign a uid to all users (even those that aren't "signed in" as far as your app is concerned). Then signing in may consist of switching some sort of state that's independent of the actual session. This way you wouldn't need to recreate the underlying socket, you'd just need to keep track of the relevant state. Does that make sense?
I can do this by re-loading the page on sign in/off.
Or a standard Ajax Ring request (which can reconfigure the session), combined with a fresh client-side call to make-channel-socket!
.
Another way would be to have sign in/off trigger disconnect and reconnect.
Sorry, not sure I follow what you mean by that?
In this case every client would have a unique 'user' id (client id really) that persisted across sign in and out.
Ahh, yes! That's what I was getting at earlier. This method gives you the most flexibility.
Any suggestions you might have would be greatly appreciated.
Okay, quick recap:
- The client doesn't need to know what her uid is, just whether or not she has one. I'll likely remove even that requirement in the next update.
- User-ids map 1-to-1 with sessions. (Hard requirement for security).
- User-ids are necessary only for
server>user
async push. - Sessions can be updated with page reloads or standard Ajax requests.
- Upgrading a socket from session-without-uid to session-with-uid requires a fresh call to
make-channel-socket!
. (Hard requirement for security). - Having a user-id may map 1-to-1 with your app's concept of being "signed in", but this is entirely at your discretion.
From that set of rules, it'll basically just be a case of finding a model/pattern that fits with your particular requirements best.
I'll keep thinking of ways of simplifying all this and/or documenting it more clearly. In the meantime please feel free to shout if anything above was unclear or if you've got any other questions.
Cheers! :-)
from sente.
Thanks for that, you're confirming a lot of what I was piecing together or guessing at.
I do need server->client push before the user is signed in (i.e. before we know the uid which would be based on the user's credentials).
There are two statements in Sente's readme that maybe you can expand upon:
-
Automatic, sensible support for users connected with multiple clients and/or devices simultaneously.
-
Realtime info on which users are connected over which protocols (v0.10.0+).
Thanks,
Bob
from sente.
Thanks for that, you're confirming a lot of what I was piecing together or
guessing at.I do need server->client push before the user is signed in (i.e. before we
know the uid which would be based on the user's credentials).
Okay, that'll then require an approach where you give anonymous users some
kind of user-id. You could have two forms of id, for example:
"not-signed-in-" and "signed-in-" and upgrade
from the former to the latter when appropriate.
There are two statements in Sente's readme that maybe you can expand upon:
- Automatic, sensible support for users connected with multiple clients
and/or devices simultaneously.The server>user async push will deliver events to every connected client
with that user-id. This includes all browser windows and devices,
So, for example, I can login as user-id "Bob" with my desktop, notebook,
and tablet simultaneously. Any server>user "Bob" async push will deliver to
all devices simultaneously, even if they're connected over different
protocols.
- Realtime info on which users are connected over which protocols
(v0.10.0+).
As of v0.10.0, the server-side make-channel-socket!
fn returns a map
which includes a :connected-uids
key which is a watchable, read-only atom
of the form {:ws #{_} :ajax #{_} :any #{_}}
.
It'll show connected user-ids by protocol.
This is especially useful for server>user async push since you'll want to
check which user-ids you want to try send an event to.
Does that make sense?
Peter Taoussanis
from sente.
Almost there :-)
I believe there's no way to change the uid associated with a connection... right?
And no way to find out how many or what connections are associated with a give uid...
Cheers,
Bob
from sente.
I believe there's no way to change the uid associated with a connection... right?
Uid == session at time of client-side chsk-make-connection!
call. So changing a uid would mean changing the sessionized :uid then reestablishing the connection.
Is that what you had in mind? Note that reestablishing a chsk connection isn't very expensive; it's basically one HTTP request.
If you wanted some way of upgrading a user's rights or identity w/o reconnecting, that'd need to be done through some indirection mechanism that you setup+maintain like a live mapping of uuids->application-level-ids.
And no way to find out how many or what connections are associated with a give uid...
That info is available, but I'm not currently exposing it. I could do, just hadn't thought it'd be useful to anyone. Can you describe your use case a little there?
from sente.
The indirection mechanism you mention is basically what I was trying to say in my original question when I was talking about layering my own user management stuff on top of Sente.
Regarding the connections associated with a user... there's a possibility (likelihood) that I'll need to know what kind of device is attached (e.g. browser, tablet, phone) and what the device capabilities are. This would allow us to limit the clients that receive 'broadcasts' based on message type to the devices that can use it. So I'll need to attach a bit of information to the client connection... which is one more argument for building something on top of Sente.
Thanks,
Bob
from sente.
there's a possibility (likelihood) that I'll need to know what kind of device is attached (e.g. browser, tablet, phone) and what the device capabilities are. This would allow us to limit the clients that receive 'broadcasts' based on message type to the devices that can use it.
Ahh okay, sure. All Sente knows about is the protocol(s) currently in use (WebSocket or Ajax) by each user id. It also has info (currently private) about how many clients are currently connected for each id.
Other info (like device type) may be discernible from the chsk handshake HTTP request, but you're correct in saying that's something you'd need to extract+maintain yourself.
So your original suggestion (layering your own user management atop Sente) seems like it'd be a good fit and quite idiomatic: I do something similar myself.
Closing this for now then, but please feel free to reopen if you run into any issues or anything else I could help clarify.
Cheers! :-)
from sente.
Just a quick heads-up that I had a thought about how I could make this all very much simpler.
The client could be auto-configured during channel socket handshake. Among other things, this'd let it determine its user-id automatically. Then any login procedure would literally just consist of terminating the current socket. The auto-recovery will kick in, reconnect, reconfigure, and any new/updated id will be picked up automatically and in a way that's still secure.
This makes the client zero config in all cases and makes migrating from not-logged-in -> logged-in users very easy.
Will try find some time to play with this properly tomorrow.
from sente.
Okay v0.13.0 is out which introduces dynamic, zero-config user-ids for easy integration with any kind of standard auth mechanism. A simple login example's included.
from sente.
Thanks a bunch!! I'll check it out immediately. Appreciate your efforts! 👍
from sente.
Okay. Wow. I just got my user management stuff to work with 0.12.0, so thought I'd check my email and what do I find but this?
On a quick read of the change log, this looks like a huge improvement. So, I'll take a little break and then rip out all my changes since yesterday morning :-)
Thanks! And congratulations!
UPDATE: have 0.13.0 integrated with my code. Easy. There's another (trivial) breaking change is that the event :chsk/ping is now called :chsk/ws-ping.
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.