I want to use websockets with Django 4.1 - say for example - just to fetch a user’s records logged in as that user.
But all examples talk about channels and Daphne show case a use-case of multi-user chat box with redis and all.
Better off I use django.setup()
as a standalone for ws:// to get these details for a logged-in user ?
This is the stand-alone script I was testing out without Django :
import asyncio, websockets, time
# Auth Middleware
async def handler(websocket, path):
data = await websocket.recv()
reply = f"FETCHING {data}"
await websocket.send(reply)
if (data == 'SOME_USER_DATA'):
for i in range(10, 20):
data = await websocket.recv()
reply = f"BOOK : {i}"
time.sleep(1) # Time to fetch data from database
await websocket.send(reply)
await websocket.send("DONE")
start_server = websockets.serve(handler, "localhost", 8989)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Redis is needed within the Channels consumers, it’s how the consumers basically track all of the different websockets across multiple users. If you’re going to have multiple people connecting concurrently, you need some way to track those separate connections.
Either way, you’re going to be running a separate process for this - personally, I’d feel more comfortable with it running in a proven async server such as Daphne (or uvicorn) than trying to handle it myself.
But if I have the websocket running separately then if 2 users connect to it, it’ll be 2 different instances, right ? Right now my requirement is just for sending back data from the server that takes a long time. Need to pass this to the browser as and when it comes until its done.
I’m not following what you’re saying here.
If you’re running an async websocket server, you have one process running an event loop. In Channels, a websocket consumer is handling the events coming from the browser, and serves as the internal connection points for other processes to send data to that browser instance. If you have an external event that is also generating an event in that event loop, your handler for that event would need to know which consumer is supposed to act on that event to send data back to the browser.
But that could be handled by user session data, right ?
Just storing something in a user’s session isn’t going to fire an event in the event loop.
That’s the key piece to channels here. In addition to listening to events for messages coming from a browser, the consumer’s channel is also available to channel’s core. So any module anywhere, with access to that channel layer’s channel can send a message to that consumer to do “something” - where “something” is identified by the contents of that message.
That’s the conceptual foundation for the “chat” app - it really is a good parallel for everything you might want to do with a channel-based app. The consumer can receive messages from the browser, and process messages passed to it by the channel layer. In the case of a chat app, what the consumer does is pass that text message out to the browser to be rendered, but that’s far from the only thing that can be done with it.