django-websocket打造简单的聊天室

1,框架DJANGO,VUE 

2,前端VUE代码




    
    
    
    聊天窗口
    {% load static %}
    



    

留言窗口


3,后端DJANGO代码

consumers.py

import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import datetime

class ChatConsumer(WebsocketConsumer):
    # websocket建立连接时执行方法
    def connect(self):
        # 从url里获取聊天室名字,为每个房间建立一个频道组
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        # 将当前频道加入频道组
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        # 接受所有websocket请求
        self.accept()

    # websocket断开时执行方法
    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    # 从websocket接收到消息时执行函数
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        # 发送消息到频道组,频道组调用chat_message方法
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    # 从频道组接收到消息后执行方法
    def chat_message(self, event):
        message = event['message']
        datetime_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        # 通过websocket发送消息到客户端
        self.send(text_data=json.dumps({
            'message': f'{datetime_str}:{message}'
        }))

routing.py

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/chat/(?P\w+)/$', consumers.ChatConsumer.as_asgi()),
]

asgi.py

"""
ASGI config for admin_demo project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
"""

# import os
#
# from django.core.asgi import get_asgi_application
#
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'admin_demo.settings')
#
# application = get_asgi_application()
import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "admin_demo.settings")

application = ProtocolTypeRouter({
    # http请求使用这个
    "http": get_asgi_application(),
    # websocket请求使用这个
    "websocket": AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})

setting.py    静态文件配置

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(os.path.dirname(__file__),'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
('css',os.path.join(STATIC_ROOT,'css').replace('\\','/') ),
('js',os.path.join(STATIC_ROOT,'js').replace('\\','/') ),
('images',os.path.join(STATIC_ROOT,'images').replace('\\','/') ),
('upload',os.path.join(STATIC_ROOT,'upload').replace('\\','/') ),
)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')

#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True  # 允许携带Cookie
CORS_ORIGIN_ALLOW_ALL = True
#channel配置
ASGI_APPLICATION = 'admin_demo.asgi.application'
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)

CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
)

4,卡点在于前后端websocket接口的用法协调性需要保持一致,后端django怎么单纯的应用vue.js,而不去用原生的jquery(非主流用法)

引用链接Django实战:channels + websocket四步打造个在线聊天室(附动图) - 知乎

此处博主用的是原生写法,我用Vue进行改写

5,大坑之线上部署:

一直出现无法读取asgi_application .网上解决办法都一样。主要原因还是包的原因.parse版本过高。  as_asgi()  问题主要是因为channels版本的问题,目前我用3.0.1就没问题,其他的不太靠谱

python3 -m pip install urllib3==1.26.6

你可能感兴趣的:(django,websocket,python)