작성
·
342
·
수정됨
0
채팅방에서 마지막 유저가 나가면 채팅방 자동 삭제
를 구현하기 위해 , 그 뒤에 추가 과제들도 구현하기 위해 channel_name
을 따로 model로 만들고 싶습니다.
channel_name
을 살펴보면 specific.19f083513f9244298b2f329aa6916165!fce7333e1805488dae51ab420eeaa6a4
으로 구성되어 있습니다.
test1, test2가 있다면 먼저 접속한 유저의 channel_name중 specific.19f083513f9244298b2f329aa6916165(!전까지)를 같이 공유해서 저장하는것 같더라구요.
-> 맞을까요?
그래서 specific.19f083513f9244298b2f329aa6916165까지는 동일하고 그 뒤에부터 다르게 저장되는것을 파악하였습니다.
specific.19f083513f9244298b2f329aa6916165를 기준으로 model을 생성해서 관리하는 방법이 괜찮은 방법인지 질문드리고 싶습니다!
서버가 강제 종료되면 이전에 channel_name이 그대로 남아있어서 최종적으로 마지막으로 나갔는지 파악하기 어려워 ChannelName를 생성해서 관리하면 괜찮지 않을까 생각했습니다.
답변 1
1
안녕하세요.
채널스 웹소켓 서버와 유저가 연결이 되어있는 상태에서 강제로 종료시켰다면, 유저와의 웹소켓 연결도 모두 끊어졌을 텐데요.
프로세스 종료 시에 SIGKILL 시그널 (Kill signal)을 받으면 프로세스가 정리할 시간도 주지 않고 바로 죽여버리지만, SIGTERM 시그널 (Termination signal)은 프로세스를 종료시키는 일반적인 접근으로서 프로세스에게 종료 시그널을 보내고 프로세스가 정리할 시간을 확보해줄 수 있습니다.
프로세스를 죽이실 때에는 SIGTERM 시그널을 보내도록 해주시고,
python manage.py runserver 시에는 Ctrl-C 입력을 하시면 SIGINT 시그널이 발생하네요.
atexit는 파이썬 기본 모듈로서, 프로세스가 종료될 때 수행될 핸들러를 등록하실 수 있습니다.
asgi.py 아래에 아래와 같이 cleanup_function을 등록하실 수 있는 데요. SIGTERM 시그널과 SIGINT 시그널에서도 cleanup_function 함수가 호출되더라구요. 그러니 cleanup_function 내에서 RoomMember의 channel_names를 빈 set으로 변경하거나 정리하는 코드를 적용해보실 수도 있지 않을까요?
import atexit
def cleanup_function():
print("Program is exiting. Cleanup function is called.")
atexit.register(cleanup_function)
그리고, channels_redis의 new_channel 함수 구현을 보면, 채널명을 정하는 로직은 아래와 같습니다.
느낌표(!) 앞의 문자열은 prefix와 client_prefix로서 이뤄지는 데요. client_prefix 값은 RedisChannelLayer 생성자에서 uuid4 값으로 1회 설정되고 계속 사용되어지고 있습니다.
RedisChannelLayer 인스턴스는 ASGI 프로세스마다 1회 생성되어서 사용되어집니다. 그러니 느낌표(!) 앞의 문자열은 각 채팅방을 식별할 수 있는 식별자가 될 수 없을 듯 합니다.
"채널 레이어를 활용한 프로세스간 통신" 수업에서 아래 슬라이드를 만들어놓고, 녹화에서는 불필요한 듯 하여 빼놓은 슬라이드입니다. 이 슬라이드에 InMemoryChannelLayer와 RedisChannelLayer에 대한 코드 비교가 있으니 참고해보시면 좋을 듯 합니다.
살펴보시고, 질문 부탁드립니다.
화이팅입니다. :-)
첨부해주신 슬라이드와 추가 코드 설명이 매우 도움이 되었습니다. 활용해서 구성해보겠습니다. 감사합니다!