この記事は3年以上前に書かれた記事で内容が古い可能性があります
DjangoでChatアプリを作る5(チャットの投稿が別画面でもリアルタイムに反映されるまで)
2019-02-18
DjangoでChatアプリを作る4(チャットの投稿ができるまで)の続き
CHANNEL_LAYERSをsettings.pyに追記する
% vim mysite/settings.py
% tail -8 mysite/settings.py CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('0.0.0.0', 6379)], }, }, }
あれ、エラー
web_1 | Cannot import BACKEND 'channels_redis.core.RedisChannelLayer' specified for default web_1 | WebSocket DISCONNECT /ws/chat/lobby/ []
channels_redisを忘れてた
% vim requirements.txt
★部分追記
% cat requirements.txt Django psycopg2 python-decouple social-auth-app-django channels channels_redis ★
docker-compose buildとdocker-compose upで立ち上げ直す
次はこんなエラーが
web_1 | raise OSError(err, f'Connect call failed {address}') web_1 | [Errno 111] Connect call failed ('0.0.0.0', 6379) web_1 | WebSocket DISCONNECT /ws/chat/lobby/ [ ]
0.0.0.0ではなく、’redis’と記載する(★部分追記)
% tail -8 mysite/settings.py CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('redis', 6379)], ★ }, }, }
次はこれ
web_1 | for res in _socket.getaddrinfo(host, port, family, type, proto, flags): web_1 | [Errno -2] Name or service not known web_1 | WebSocket DISCONNECT /ws/chat/lobby/ [ ]
redisサービスをあげてなかった(★部分追記)
% cat docker-compose.yml version: '3' services: db: image: postgres redis: ★ image: redis:2.8 ★ ports: ★ - "6379:6379" ★ web: build: . command: python3 manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" depends_on: - db - redis ★
docker-compose buildとdocker-compose upで立ち上げ直す
docker-compose upでこんなん出てくる
redis_1 | _._ redis_1 | _.-``__ ''-._ redis_1 | _.-`` `. `_. ''-._ Redis 2.8.23 (00000000/0) 64 bit redis_1 | .-`` .-```. ```\/ _.,_ ''-._ redis_1 | ( ' , .-` | `, ) Running in stand alone mode redis_1 | |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 redis_1 | | `-._ `._ / _.-' | PID: 1 redis_1 | `-._ `-._ `-./ _.-' _.-' redis_1 | |`-._`-._ `-.__.-' _.-'_.-'| redis_1 | | `-._`-._ _.-'_.-' | http://redis.io redis_1 | `-._ `-._`-.__.-'_.-' _.-' redis_1 | |`-._`-._ `-.__.-' _.-'_.-'| redis_1 | | `-._`-._ _.-'_.-' | redis_1 | `-._ `-._`-.__.-'_.-' _.-' redis_1 | `-._ `-.__.-' _.-' redis_1 | `-._ _.-' redis_1 | `-.__.-'
最後はこの文言出てくる
web_1 | Django version 2.1.7, using settings 'mysite.settings' web_1 | Starting ASGI/Channels version 2.1.7 development server at http://0.0.0.0:8000/ web_1 | Quit the server with CONTROL-C.
consumers.pyをコピペし直す
% vim chat/consumers.py
% cat chat/consumers.py from asgiref.sync import async_to_sync from channels.generic.websocket import WebsocketConsumer import json class ChatConsumer(WebsocketConsumer): def connect(self): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name # Join room group async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() def disconnect(self, close_code): # Leave room group async_to_sync(self.channel_layer.group_discard)( self.room_group_name, self.channel_name ) # Receive message from WebSocket def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] # Send message to room group async_to_sync(self.channel_layer.group_send)( self.room_group_name, { 'type': 'chat_message', 'message': message } ) # Receive message from room group def chat_message(self, event): message = event['message'] # Send message to WebSocket self.send(text_data=json.dumps({ 'message': message }))
できた、2画面で同期とれている
Safariの方
Chromeの方でhiと送信する
すると、Safariの方でも反映されている
最終的なディレクトリ構造はこんな感じ
% tree . └── mysite ├── Dockerfile ├── chat │ ├── __init__.py │ ├── __pycache__ │ ├── consumers.py │ ├── routing.py │ ├── templates │ │ └── chat │ │ ├── index.html │ │ └── room.html │ ├── urls.py │ ├── views.py ├── docker-compose.yml ├── manage.py ├── mysite │ ├── __init__.py │ ├── __pycache__ │ ├── asgi.py │ ├── login │ │ ├── __pycache__ │ │ └── views.py │ ├── routing.py │ ├── settings.py │ ├── templates │ │ ├── base.html │ │ ├── home.html │ │ └── registration │ │ ├── login.html │ ├── urls.py │ └── wsgi.py ├── requirements.txt
次はせっかくなので、ログインユーザだけチャットできる世界を作りたい