안녕하세요 선생님,
91
작성한 질문수 23
#consumers.py
from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer
from chat.models import Room
# 모든 유저가 고정된 채널 레이어 그룹을 가질것.
class ChatConsumer(JsonWebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
SQUARE_GROUP_NAME = "square"
self.group_name = [SQUARE_GROUP_NAME]
self.room = None
def connect(self):
user = self.scope['user']
if not user.is_authenticated:
self.close()
else:
room_name = self.scope['url_route']['kwargs']['room_pk']
try:
self.room = Room.objects.get(pk=room_name)
except Room.DoesNotExist: #지정 룸 pk에 룸 인스턴스가 없을 경우 웹소켓 연결요청 수락.
pass
else:
self.group_name = self.SQUARE_GROUP_NAME
is_new_join = self.room.user_join(self.channel_name, user)
if is_new_join:
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
"type": "chat.user.join",
"username": user.username,
}
)
async_to_sync(self.channel_layer.group_add)(
self.group_name,
self.channel_name
)
self.accept()
def disconnect(self, code):
if self.group_name:
async_to_sync(self.channel_layer.group_discard)(
self.group_name,
self.channel_name
)
user = self.scope['user']
if self.room is not None:
is_last_leave = self.room.user_leave(self.channel_name, user)
if is_last_leave:
async_to_sync(self.channel_layer.group_send)(
self.group_name,
{
"type": "chat.user.leave",
"username": user.username,
}
)
def chat_user_join(self, message_dict):
self.send_json({
"type": "chat.user.join",
"username": message_dict["username"],
})
def chat_user_leave(self, message_dict):
self.send_json({
"type": "chat.user.leave",
"username": message_dict["username"],
})
def chat_message(self, message_dict):
self.send_json({
"type": "chat.message",
"message": message_dict["message"],
"sender": message_dict["sender"],
})
def receive_json(self, content, **kwargs):
user = self.scope["user"]
_type = content["type"]
if _type == "chat.message":
message = content["message"]
sender = user.username
async_to_sync(self.channel_layer.group_send)(
self.SQUARE_GROUP_NAME,
{
"type": "chat.message",
"message": message,
"sender": sender,
}
)
else:
print(f"Invalid message type : ${_type}")
room_name = self.scope['url_route']['kwargs']['room_pk']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
KeyError: 'room_pk'
이런 에러가 나서, urls.py, views.py, index.html도 맞춰줘 봤지만, 잘 해결이 되질 않습니다. 어떤식으로 이 에러를 처리해야할까요. 오늘도 좋은 하루 되시길 바랍니다.
감사합니다.
답변 1
1
안녕하세요.
self.scope["url_route"]["kwargs"] 사전은 websocket_urlpatterns 에 명시한 path에 정의한 값들로 구성됩니다. 장고 View 함수에서 인자로 전달받는 값과 같습니다.
그러니 path("ws/chat/<int:room_pk>/", ...) 처럼 room_pk 항목이 있으셔야 합니다.
살펴보시고 댓글 남겨주세요. :-)
0
지금 채팅방 입장 퇴장 알림 부분을 하고 있었습니다.
이 부분을 하기 위해서 모델과 연동하여 하는데, 제 생각에는 여태까지 채팅 Url을 Room 모델과 관계없이 그냥 열어서 쓰다가 발생한거같습니다. 채팅방 만들기 기능을 안넣고, 그냥 광장채팅방만 만들어서 쓰려고 하거든요. 이런 경우는 room 모델에 그냥 광장채팅방 이름을 만들어서 넣어주면 되는건가요?
1
Room 은 채팅방 접속 여부를 확인할 목적일 뿐이구요.
단일 채팅방만 운영하실 경우, 그룹명이 정해져있는 것이니까 굳이 따로 광장채팅방 room을 생성하실 필요가 없을 듯 하구요.
Consumer에서 속할 그룹명이 정해져있는 상황이니, 앞선 liveblog 예시처럼 Consumer 클래스의 groups 리스트 속성으로 groups = ["square"] 로 쓰시면, consumer에서 알아서 지정 그룹에 추가하고 제거까지 해줍니다.
유저목록 확인 문제 질문드립니다.
0
164
2
하나의 채팅방만 만들어보려고 하는데 잘 안되고 있습니다.
0
103
1
도커와 연동 관련 질문드립니다.
0
205
3
채팅방 참여자 목록 - 채팅방 입장/퇴장 실시간 이벤트 처리
0
165
2
안녕하세요, onopen() 문제로 질문드립니다.
0
137
2
Consumer Instances 관련 질문 있습니다.
0
72
2
안녕하세요, 요청은 채널스에서 먼저 받고, http 요청은 장고를 통해서 처리한다고 하셨는데요.
0
79
2
기능 구현 질문 드립니다.
0
115
1
git에 있는 코드를 다운 받아 실행 해봤는데 에러가 났습니다.
0
153
2
ValueError: No route found for path 'ws/liveblog/'.
0
134
2
지정 경로에 템플릿 파일 만드는 단축키가 뭔가요?
0
121
2
채팅 내역을 영구적으로 저장하고 싶습니다.
0
89
1
질문이 있습니다.
0
164
1
구독 채팅 구현
0
212
1
헷갈려서 질문드립니다.
0
355
2
@login_required 장식자를 적용한후에는 로그인을 성공하면 채팅방으로 어떻게 이동을 하는 건가요?
1
276
1
docker run -d --restart always --name redis7 --publish 6379:6379 redis:7
0
261
1
websocket 자바스크립트 클라이언트 구현?
0
361
1
메세지 리액션 : 좋아요. 질문 드립니다.
0
359
1
{유저명}님이 메세지 입력 중입니다. 메세지 질문드립니다.
0
610
1
채팅 로비에서 유저수 노출을 위하여
0
326
1
채팅방에서 마지막 유저가 나가면 채팅방 자동 삭제 질문드립니다.
0
432
1
동기방식의 consumer 클래스와 비동기방식의 consumer클래스의 차이가 뭔지 궁금합니다.
0
425
1
라이브러리 인식
0
416
2





