نمط التوجيه لرابيت إم كيو (Direct Mode) في جافا يستخدم نوع تبادل DirectExchange. الفرق عن نمط النشر والاشتراك هو أن تبادل الـ Direct يقوم بتوصيل الرسائل إلى الطوابور مع معلمات التوجيه التي تطابق تمامًا. تُظهر الهندسة المعمارية في الصورة أدناه:

نمط رابيت إم كيو 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، لأن مفتاح التوجيه لا يتطابق، لن يتلق أي رسائل.