نمط التوجيه لرابيت إم كيو (Direct Mode) في جافا يستخدم نوع تبادل DirectExchange. الفرق عن نمط النشر والاشتراك هو أن تبادل الـ Direct يقوم بتوصيل الرسائل إلى الطوابور مع معلمات التوجيه التي تطابق تمامًا. تُظهر الهندسة المعمارية في الصورة أدناه:
نصيحة: بغض النظر عن نمط عمل رابيت إم كيو المستخدم، تكمن الفرق في نوع تبادل الاستخدام ومعلمات التوجيه.
1. البرامج التعليمية الأساسية
الرجاء قراءة الأقسام التالية لفهم المعرفة المتعلقة:
- مفاهيم رابيت إم كيو الأساسية
- مبدأ نمط التوجيه في رابيت إم كيو
- البداية السريعة لجافا مع رابيت إم كيو (يجب قراءتها، حيث لن تكرر الأقسام التالية الشفرة البرمجية إلا لعرض الشفرة الرئيسية فقط)
- نمط النشر والاشتراك لجافا مع رابيت إم كيو (يجب قراءتها، حيث تختلف بنية الشفرة تقريبًا فقط، فقط يختلف نوع التبادل ومعلمات التوجيه)
2. تعريف التبادل المباشر
في Spring AMQP، الصف المقابل لتبادل المباشر هو DirectExchange. نحدد التبادل من خلال صف الإعداد لربيع الزخم.
package com.tizi365.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QueueConfig {
@Bean
public DirectExchange direct() {
// نحدد التبادل
// المعلمة هي اسم التبادل والذي يجب أن يكون فريدًا
return new DirectExchange("tizi365.direct");
}
}
نصيحة: كل من منتج الرسائل والمستهلك يتطلبان تبادلًا.
3. إرسال الرسائل
نقوم بإرسال الرسائل إلى التبادل، الذي يقوم بتوصيل الرسائل إلى الطوابير المقابلة بناءً على قواعد التوجيه.
package com.tizi365.rabbitmq.service;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class SendService {
@Autowired
private RabbitTemplate template;
@Autowired
private DirectExchange direct;
// لغرض العرض، نستخدم مهمة مجدولة لإرسال رسالة كل ثانية
@Scheduled(fixedDelay = 1000, initialDelay = 1000)
public void send() {
// محتوى الرسالة
String message = "مرحبًا بالعالم!";
// إرسال الرسالة
// المعلمة الأولى هي اسم التبادل
// المعلمة الثانية هي مفتاح التوجيه. مع تبادل مباشر، يتم توصيل الرسالة إلى الطابور الذي يطابق مفتاح التوجيه "tizi365"
// المعلمة الثالثة هي محتوى الرسالة، والتي تدعم أي نوع طالما يمكن تسلسله
template.convertAndSend(direct.getName(), "tizi365", message);
System.out.println("تم إرسال الرسالة '" + message + "'");
}
}
نصيحة: يُرجى الانتباه إلى المعلمة الثانية في طريقة convertAndSend، حيث أن هذه المعلمة حرجة.
4. تلقي الرسائل
4.1 تعريف الصفوف وربط المبادل
لاستهلاك الرسائل من صف، يجب أن تقوم أولاً بتعريف صف، ثم ربط الصف بالمبادل المستهدف. الكود التالي يعرف صفين ويربطهما بنفس المبادل:
package com.tizi365.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QueueConfig {
@Bean
public DirectExchange direct() {
// تعريف المبادل
// المعامل هو اسم المبادل، الذي يجب أن يكون فريدًا
return new DirectExchange("tizi365.direct");
}
@Bean
public Queue queue1() {
// تعريف الصف 1
return new Queue("tizi365.direct.queue1");
}
@Bean
public Queue queue2() {
// تعريف الصف 2
return new Queue("tizi365.direct.queue2");
}
@Bean
public Binding binding1(DirectExchange direct, Queue queue1) {
// تعريف ربط الصف 1 بالمبادل المباشر بمفتاح توجيه "tizi365"
// عندما يطابق مفتاح التوجيه "tizi365"، سيسلم المبادل الرسائل إلى الصف 1
return BindingBuilder.bind(queue1).to(direct).with("tizi365");
}
@Bean
public Binding binding2(DirectExchange direct, Queue queue2) {
// تعريف ربط الصف 2 بالمبادل المباشر بمفتاح توجيه "baidu"
// عندما يطابق مفتاح التوجيه "baidu"، سيسلم المبادل الرسائل إلى الصف 2
return BindingBuilder.bind(queue2).to(direct).with("baidu");
}
}
4.2 تعريف مستمعي الصفوف
تعريف مستمعي الرسائل باستخدام تعليق RabbitListener لاستهلاك الرسائل من الصفوف المحددة:
package com.tizi365.rabbitmq.listener;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
// اسمح لـ Spring بإدارة الفئة الحالية
@Component
public class DemoListener {
// تعريف مستمع لاستهلاك الرسائل من الصف 1
@RabbitListener(queues = "tizi365.direct.queue1")
public void receive1(String msg) {
System.out.println("تم استقبال رسالة من الصف 1: " + msg);
}
// تعريف مستمع لاستهلاك الرسائل من الصف 2
@RabbitListener(queues = "tizi365.direct.queue2")
public void receive2(String msg) {
System.out.println("تم استقبال رسالة من الصف 2: " + msg);
}
}
نظرًا لأن الصف 1 هو الوحيد الذي لديه مفتاح توجيه "tizi365" عند ربطه بالمبادل، يمكن للصف 1 فقط استقبال الرسائل. الصف 2، لأن مفتاح التوجيه لا يتطابق، لن يتلق أي رسائل.