اذهب إلى المحتوى
  • 1

كيف اعمل نظام الاشعارات في django

Zakaria Bellour

السؤال

Recommended Posts

  • 3
  1.  قم بإعداد ASGI لتطبيقك 

قبل البدء ، قم بتثبيت التبعيات المدرجة أدناه والتي ستكون ضرورية لإعداد WebSockets.

Django                             3.0(or greater)
channels                           3.0.4
channels-redis                     3.3.1

بمجرد تثبيت التبعيات المذكورة أعلاه ، سيتعين علينا إضافة "channels" إلى قائمة قسم "INSTALLED_APPS" في ملف settings.py.

بشكل افتراضي ، تعمل تطبيقات Django على خوادم WSGI ولهذا السبب سنحتاج إلى إعداد تطبيقنا يدويًا للتشغيل على خادم ASGI.
انتقل إلى ملف settings.py وأضف السطر التالي.
ملاحظة: "your_project" في الكود أدناه هو اسم الدليل للمجلد الجذر الذي سيحتوي على ملف "settings.py"

ASGI_APPLICATION = 'your_project.asgi.application'

الآن لكي يعمل جزء الكود أعلاه ، سيتعين علينا التأكد من وجود ملف "asgi.py" في دليل التطبيق الجذر لدينا مثل:1_R9LK9gpYq9X58AF3DdDodQ.thumb.png.6eeff35f8153a49ebd937060c8ccc0c2.png

2) إنشاء نموذج الإشعارات 

class notifications(models.Model):
  user_sender=models.ForeignKey(Users,null=True,blank=True,related_name='user_sender',on_delete=models.CASCADE)
  user_revoker=models.ForeignKey(Users,null=True,blank=True,related_name='user_revoker',on_delete=models.CASCADE)
  status=models.CharField(max_length=264,null=True,blank=True,default="unread")
  type_of_notification=models.CharField(max_length=264,null=True,blank=True)

3) قم بإعداد ملف customers.py الخاص بك

المستهلكون إلى WebSockets كوجهات النظر إلى HTTP. ملف customers.py هو المكان الذي يتم فيه التعامل مع جميع طلبات WebSocket وإرسالها مرة أخرى إلى الواجهة الأمامية. هناك أنواع مختلفة من مستهلكي WebSocket مثل "AsynConsumer" و "WebSocketConsumer" و "AsyncWebSocketConsumers" على سبيل المثال لا الحصر.

انتقل إلى أحد التطبيقات داخل مشروعك وأنشئ ملف "customers.py".

قم باستيراد التبعيات التالية

from channels.generic.websocket import WebsocketConsumer,AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from asgiref.sync import async_to_sync,sync_to_async
from channels.layers import get_channel_layer

يحتاج كل "مستهلك" في قنوات Django إلى ثلاث طرق محددة.
الاتصال والاستلام وقطع الاتصال.

يتم استخدام الاتصال لإنشاء اتصالات بين الواجهة الأمامية والخلفية.

يُستخدم الاستلام للتعامل مع الطلبات المرسلة من الواجهة الأمامية والتعامل معها وفقًا لذلك.

يُستخدم فصل الاتصال للتعامل مع ما يجب أن يحدث إذا تم إغلاق WebSocket أو إيقاف تشغيله.

إذن كيف ستعمل WebSockets لدينا؟ سيقوم WebSocket الخاص بنا أولاً "بإنشاء" اتصال. بمجرد إنشاء الاتصال ، فإن الواجهة الخلفية "تستمع" لأي حدث قد ترسله الواجهة الأمامية إليه وتعالج ذلك في طريقة "الاستلام".

دعونا نلقي نظرة خاطفة على ذلك

سننشئ أولاً وظيفة سيتم استخدامها لإنشاء كائن إعلام في كل حدث.

@database_sync_to_async
def create_notification(receiver,typeof="task_created",status="unread"):
    notification_to_create=notifications.objects.create(user_revoker=receiver,type_of_notification=typeof)
    print('تم')
    return (notification_to_create.user_revoker.username,notification_to_create.type_of_notification)

بعد ذلك سنلقي نظرة على "المستهلك" الرئيسي لدينا. دعونا نلقي نظرة على طريقة الاتصال أولاً. 

class NotificationConsumer(AsyncWebsocketConsumer):
async def websocket_connect(self,event):
        print('تم الإتصال',event)
        print('تم اﻷمر')
        print(self.scope['user'].id)
        await self.accept()
await self.send(json.dumps({
            "type":"websocket.send",
            "text":"مرحبا"
        }))

4) أدخل Redis


الآن مع طريقة الاتصال بعيدًا عن الطريق. سنحتاج إلى إعداد "Redis". Redis هو مخزن بنية بيانات مفتوح المصدر (مرخص من BSD) ، يستخدم كقاعدة بيانات وذاكرة تخزين مؤقت ووسيط رسائل. إنه جزء لا يتجزأ من تشغيل WebSockets الخاص بنا.

انتقل إلى ملف settings.py وأضف الكود التالي لإعداد Redis.

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("127.0.0.1", 6379)],
        },
    },
}

5) إعداد جهاز التوجيه URL الخاص بنا

import os
from channels.routing import ProtocolTypeRouter,URLRouter
from channels.auth import AuthMiddlewareStack
from stories import consumers

from django.urls import re_path,path
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mirror_project.settings')
import stories.routing
application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket":AuthMiddlewareStack(
URLRouter(
[path('stories/notification_testing/',consumers.NotificationConsumer.as_asgi())]
))
    
    
    
})

إذا نظرت إلى جزء "ProtocolTypeRouter" داخل الكود ، فلدينا قسمان ، "HTTP" و "WebSocket".
"HTTP" مخصص لـ ASGI لرعاية طلبات العرض التقليدية بينما يتم استخدام "WebSocket" للتعامل مع طلبات مأخذ التوصيل. ملاحظة ، لقد حددت "مسارًا" يحتوي على "مسار" وبجانبه يوجد شيء مشابه لطريقة عرض.
رمز يرتبط بـ "فئة مستهلك الإشعارات".

6) جمع كل ذلك معًا

السبب في قيامنا بدمج Redis في المقام الأول هو أننا نحتاج إلى طريقة "لبث" حدث إنشاء الإشعارات متى تم إنشاؤه في "غرفة". وبعد ذلك يمكن للواجهة الأمامية التحقق من المعلومات وتقرر إما عرضها أو رفضها. دعونا نلقي نظرة على الكود النهائي الخاص بنا لملف customers.py.

@database_sync_to_async
def get_user(user_id):
    try:
        return Users.objects.get(id=user_id)
    except:
        return AnonymousUser()
@database_sync_to_async
def create_notification(receiver,typeof="task_created",status="unread"):
    notification_to_create=notifications.objects.create(user_revoker=receiver,type_of_notification=typeof)
    print('تم')
    return (notification_to_create.user_revoker.username,notification_to_create.type_of_notification)
class NotificationConsumer(AsyncWebsocketConsumer):
async def websocket_connect(self,event):
        print(self.scope)
        await self.accept()
await self.send(json.dumps({
            "type":"websocket.send",
            "text":"مرحبا"
        })) 
        self.room_name='test_consumer'   
        self.room_group_name='test_consumer_group'
        await self.channel_layer.group_add(self.room_group_name,self.channel_name)
        self.send({
            "type":"websocket.send",
            "text":"room made"
        })
async def websocket_receive(self,event):
        print(event)
        data_to_get=json.loads(event['text'])
        user_to_get=await get_user(int(data_to_get))
        print(user_to_get)
        get_of=await create_notification(user_to_get)
        self.room_group_name='test_consumer_group'
        channel_layer=get_channel_layer()
        await (channel_layer.group_send)(
            self.room_group_name,
            {
                "type":"send_notification",
                "value":json.dumps(get_of)
            }
)
        print('receive',event)
async def websocket_disconnect(self,event):
        print('disconnect',event)
async def send_notification(self,event):
        await self.send(json.dumps({
            "type":"websocket.send",
            "data":event
        }))
        print('تم')
        print(event)

6) اختبر اتصالات socket الخاص بك

ws://127.0.0.1:8000/stories/notification_testing/

7) قم بإنشاء إعلام عن طريق إرسال معرف المستخدم.

أخيرًا ، نرسل معرف مستخدم إلى WebSocket الخاص بنا

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...