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

السؤال

Recommended Posts

  • 0
نشر

كانت غرفة الدردشة هي الخطوة الأساسية نحو إنشاء مشاريع حية وفي الوقت الفعلي. ستكون صفحة الدردشة التي سننشئها عبارة عن نموذج HTML بسيط مع نص h1 بسيط مع اسم المستخدم الحالي ورابط لتسجيل الخروج إلى المستخدم الذي قام بتسجيل الدخول للتو. قد تحتاج إلى التعليق على السطر حتى نقوم إنشاء نظام مصادقة لهذا الغرض. هذا يضمن أنه عند قيام مستخدمين بالدردشة ، يمكن لأحدهما تسجيل الخروج ولن يؤثر ذلك على المستخدم الآخر. سيظل الآخر مسجلاً الدخول ويمكنه إرسال الرسائل واستلامها. 

المتطلبات الأساسية:

  • Django
  • Django Migrations
  • Django Channel

نضيف channels الى installed apps 

INSTALLED_APPS = [
	'chat.apps.ChatConfig',
	
	'django.contrib.admin',
	'django.contrib.auth',
	'django.contrib.contenttypes',
	'django.contrib.sessions',
	'django.contrib.messages',
	'django.contrib.staticfiles',
	
	# اضافة القنوات
	'channels' ,
]

اضبط تطبيق ASGI على ملف ASGI الافتراضي في المشروع. الآن قم بتشغيل الخادم ، ستلاحظ أن خادم ASGI سيحدث على خادم Django وسيدعم ASGI الآن.

ASGI_APPLICATION = 'ChatApp.asgi.application'

أنشئ تطبيقًا جديدًا يحتوي على جميع وظائف الدردشة. لإنشاء تطبيق 

python manage.py startapp chat

دالة العرض 

from django.shortcuts import render, redirect


def chatPage(request, *args, **kwargs):
	if not request.user.is_authenticated:
		return redirect("login-user")
	context = {}
	return render(request, "chat/chatPage.html", context)
<!DOCTYPE html>
<html>
<body>
	<center><h1>Hello , Welcome to my chat site ! {{request.user}}</h1></center>
	<br>
	{% if request.user.is_authenticated %}
	<center> Logout the chat Page <a href = "{% url 'logout-user' %}">Logout</a></center>
	{% endif %}
	<div
	class="chat__item__container"
	id="id_chat_item_container"
	style="font-size: 20px"
	>
	<br />
	<input type="text" id="id_message_send_input" />
	<button type="submit" id="id_message_send_button">Send Message</button>
	<br />
	<br />
	</div>
	<script>
	const chatSocket = new WebSocket("ws://" + window.location.host + "/");
	chatSocket.onopen = function (e) {
		console.log("The connection was setup successfully !");
	};
	chatSocket.onclose = function (e) {
		console.log("Something unexpected happened !");
	};
	document.querySelector("#id_message_send_input").focus();
	document.querySelector("#id_message_send_input").onkeyup = function (e) {
		if (e.keyCode == 13) {
		document.querySelector("#id_message_send_button").click();
		}
	};
	document.querySelector("#id_message_send_button").onclick = function (e) {
		var messageInput = document.querySelector(
		"#id_message_send_input"
		).value;
		chatSocket.send(JSON.stringify({ message: messageInput, username : "{{request.user.username}}"}));
	};
	chatSocket.onmessage = function (e) {
		const data = JSON.parse(e.data);
		var div = document.createElement("div");
		div.innerHTML = data.username + " : " + data.message;
		document.querySelector("#id_message_send_input").value = "";
		document.querySelector("#id_chat_item_container").appendChild(div);
	};
	</script>
</body>
</html>

تنفيذ WebSockets ، غير المتزامن ، وقنوات Django

حتى الآن قمنا بإعداد مشروع Django القياسي. بعد تنفيذ تطبيق Django. حان الوقت الآن لإنشاء تطبيق ASGI.

python manage.py makemigrations
python manage.py migrate

افتح Routing.py وأنشئ مسارًا لـ ChatConsumer (والذي سننشئه في الخطوة التالية). الآن لدينا نوعان من المسارات في المشروع. الأول هو urls.py المخصص لتوجيه Django الأصلي لعناوين URL ، والآخر مخصص لـ WebSockets لدعم ASGI لـ Django.

from django.urls import path , include
from chat.consumers import ChatConsumer

# هنا ، يتم التوجيه إلى عنوان URL ChatConsumer الذي
# سيتولى وظيفة الدردشة.
websocket_urlpatterns = [
	path("" , ChatConsumer.as_asgi()) ,
]
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
	async def connect(self):
		self.roomGroupName = "group_chat_gfg"
		await self.channel_layer.group_add(
			self.roomGroupName ,
			self.channel_name
		)
		await self.accept()
	async def disconnect(self , close_code):
		await self.channel_layer.group_discard(
			self.roomGroupName ,
			self.channel_layer
		)
	async def receive(self, text_data):
		text_data_json = json.loads(text_data)
		message = text_data_json["message"]
		username = text_data_json["username"]
		await self.channel_layer.group_send(
			self.roomGroupName,{
				"type" : "sendMessage" ,
				"message" : message ,
				"username" : username ,
			})
	async def sendMessage(self , event) :
		message = event["message"]
		username = event["username"]
		await self.send(text_data = json.dumps({"message":message ,"username":username}))

اكتب الكود أدناه في asgi.py لجعله يعمل مع sockets وإنشاء المسارات.

import os
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ChatApp.settings')

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter , URLRouter
from chat import routing

application = ProtocolTypeRouter(
	{
		"http" : get_asgi_application() ,
		"websocket" : AuthMiddlewareStack(
			URLRouter(
				routing.websocket_urlpatterns
			)
		)
	}
)

يحدد هذا الكود طبقة القناة التي سنعمل فيها ونشارك البيانات. بالنسبة إلى مستوى النشر والإنتاج ، لا تستخدم InMemoryChannelLayer ، لأن هناك فرصًا كبيرة لتسرب البيانات. هذا ليس جيدًا للإنتاج. للإنتاج ، استخدم قناة Redis.

ChatApp / settings.py

CHANNEL_LAYERS = {
	"default": {
		"BACKEND": "channels.layers.InMemoryChannelLayer"
	}
}

 

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...