async def connect(self):
self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
self.redis = redis.Redis(connection_pool=pool)
logger.info("channel_name:{} / group_name {}".format(self.channel_name,self.room_group_name))
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
for key in self.redis.keys():
if self.redis.type(key).decode() == "zset":
print("key:",key)
print("len:",len(self.redis.zrange(key,0,-1)))
async def disconnect(self, close_code):
logger.info("somehow disconnect")
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
I have this script for websockt connection.
then
I am directly checking the record in redis
to get the current members of chatroom.
If a user log-out and call disconnect
, session is disappeared.
However If a user didn't call the disconnect
function, session will be stored in redis table forver.
How can I remove the old session or set the timeout??
In a Django WebSocket (using Channels) setup, when users disconnect properly, their session is removed. However, if they don't call the disconnect()
function (e.g., due to a network issue or force closing the browser), their session remains in Redis forever.
Here are some steps you can follow to remove stale sessions:
1. When a user connects, store their session with a timestamp and set an expiry for the room:
import time
import redis
async def connect(self):
self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
self.redis = redis.Redis(connection_pool=pool)
timestamp = time.time()
self.redis.zadd(self.room_group_name, {self.channel_name: timestamp})
self.redis.expire(self.room_group_name, 600) # Auto-remove if inactive for 10 minutes
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
await self.accept()
2. When a user disconnects, remove them from the Redis set:
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
self.redis.zrem(self.room_group_name, self.channel_name)
3. Before checking active users, clean up sessions older than 10 minutes:
self.redis.zremrangebyscore(self.room_group_name, 0, time.time() - 600)