I'm using flask_socketio.
@socketio.on('client_connected')
def handle_client_connect_event(data):
if current_user.is_authenticated:
thread = socketio.start_background_task(background_thread, user_id=current_user.id)
logger.info('server socket client_connected, user:{}', current_user.id)
emit('server_response', {'data': {'job_id': 'job1', 'name': 'hello'}})
else:
logger.info('server socket client_connected, user not authenticated.....')
def background_thread(user_id):
pubsub = redisc.pubsub()
redis_suscriber = redis_channel+str(user_id)
pubsub.psubscribe(redis_suscriber)
logger.info("new thread for: "+redis_suscriber)
for item in pubsub.listen():
logger.info('message received:{}', item)
data_item = item['data']
if isinstance(data_item, bytes):
try:
data_item = json.loads(data_item)
job_id = data_item['job_id']
log_data = data_item['log']
data = {'data': {'job_id': job_id, 'user_id': user_id,
'log': security_util.base64_decrypt(log_data).decode("utf-8")}}
socketio.emit('server_response', data)
except ValueError as e:
logger.error("Error decoding msg to microservice: {}", str(e))
@socketio.on('disconnect')
def disconnected():
if current_user.is_authenticated:
logger.info('user:{} disconnected', current_user.id)
else:
logger.info('client disconnected, user not authenticated.....')
There are js code to establish websocket connection from web browser page to flask server.
When the web browser page is closed, "for item in pubsub.listen():" is still functioning.
So when I open the page and close the page for 3 times, flask server will subscribe the same redis topic for 3 times, and emit the same websocket message for 3 times.
Is there a way to terminate "def background_thread(user_id)" after the web browser page is closed(js client disconnected from websocket server)?
start_background_task()function returns a task identifier, so you do know which task belongs to each client. You have to keep that state somewhere, so that you can then recover the task that belongs to a client and signal it to end. - Miguel