inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

파이썬/장고로 웹채팅 서비스 만들기 (Feat. Channels) - 기본편

채팅방 단위로 그룹 채팅

하나의 채팅방만 만들어보려고 하는데 잘 안되고 있습니다.

103

sunnnwo

작성한 질문수 23

0

안녕하세요 선생님. 인증받지 않은 유저의 웹소켓 접근을 거부하려고 하는데요,

Traceback (most recent call last):
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/django/contrib/staticfiles/handlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/routing.py", line 62, in __call__
    return await application(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sunnnwo/workspace/pongchatT/venv/lib/python3.11/site-packages/channels/middleware.py", line 24, in __call__
    return await self.inner(scope, receive, send)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'list' object is not callable
WebSocket DISCONNECT /ws/chat/test/chat/ [127.0.0.1:61013]
HTTP GET /chat/ 200 [0.01, 127.0.0.1:61007]
/Users/sunnnwo/workspace/pongchat/mysite/asgi.py changed, reloading.
Watching for file changes with StatReloader

아래와 같이 설정하고 실행해봤는데,  위와 같은 에러가 발생했습니다. AuthMiddlewareStack을 이용하여 인증된 사용자만 채팅할 수 있게 하려면 어느 부분을 수정해야할까요.

감사합니다. 좋은 하루되세요.

asgi.py


application = ProtocolTypeRouter({
	"http" : django_asgi_app,
 	"websocket" : AuthMiddlewareStack(
		app.routing.websocket_urlpatterns +
		chat.routing.websocket_urlpatterns,
 ),
})

consumers.py

from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer

# 모든 유저가 고정된 채널 레이어 그룹을 가질것.
class ChatConsumer(JsonWebsocketConsumer):
    SQUARE_GROUP_NAME = "square"
    groups = [SQUARE_GROUP_NAME]

    def receive_json(self, content, **kwargs):
        # user = self.scope["user"]

        user = self.scope["user"]
        _type = content["type"]

        if not user.is_authenticated:
            self.close()

        else:
            if _type == "chat.message":

                message = content["message"]
                async_to_sync(self.channel_layer.group_send)(
                    self.SQUARE_GROUP_NAME,
                    {
                       "type": "chat.message",
                        "message": message,
                        
                    }
                )
            else:
                print(f"Invalid message type : ${_type}")

    def chat_message(self, message_dict):
        self.send_json({
            "type": "chat.message",
            "message": message_dict["message"],
          
        })

chat/routing.py

from django.urls import path, re_path
from chat import consumers

websocket_urlpatterns = [
    path("ws/chat/<str:room_name>/chat/", consumers.ChatConsumer.as_asgi()),
]

chat/urls.py

urlpatterns=[
    path("", views.index, name = "index"),
    path("<str:room_name>/chat/", views.room_chat, name = "room_chat" ),
    ]

python django django-channels

답변 1

1

이진석

안녕하세요.

TypeError: 'list' object is not callable 예외가 발생한 상황입니다. 에러 메시지를 잘 보시면 list 객체는 호출할 수 없다는 내용인데요. 리스트 객체를 호출한 상황이라는 거죠. 함수처럼 호출되어야하는 부분에 리스트 값이 들어간 상황으로 예상할 수 있습니다.

asgi.py 코드를 보시면, AuthMiddlewareStack 미들웨어 스택에 urlpatterns 리스트를 그대로 넘기고 있습니다. AuthMiddlewareStack 는 asgi app (함수처럼 호출할 수 있습니다.)을 인자로 받고, asgi app을 반환합니다. 그런데 리스트를 넘기셔서 현재의 오류가 발생하신 듯 보입니다.

urlpatterns 리스트는 URLRouter 앱으로 감싸주셔야 asgi app 으로 처리됩니다. AuthMiddlewareStack(URLRouter(urlpatterns + urlpatterns))와 같은 포맷으로 구현하심면 되실 듯 하구요.

room_chat 뷰에서 미인증 유저로부터의 요청은 거부토록 먼저 구현하구요. 웹소켓 단에서는 Consumer에서 연결요청을 받을 때 connect 메서드가 호출이 되고, 이때 연결을 수락할려면 self.accept() 를 호출하여 요청을 수락하고, 연결을 거부할려면 self.close()를 호출하시어 거부하실 수 있습니다.

살펴보시고 댓글 남겨주세요. 화이팅입니다. :-)

1

sunnnwo

감사합니다. 선생님. 항상 건강하십쇼!

유저목록 확인 문제 질문드립니다.

0

164

2

안녕하세요 선생님,

0

91

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